fetch太慢去除历史提交记录

This commit is contained in:
gedoor
2022-01-03 23:59:44 +08:00
commit 51c16a1efc
1294 changed files with 194322 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
/build
/so
+227
View File
@@ -0,0 +1,227 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'de.timfreiheit.resourceplaceholders'
apply from: 'download.gradle'
static def releaseTime() {
return new Date().format("yy.MMddHH", TimeZone.getTimeZone("GMT+8"))
}
def name = "legado"
def version = "3." + releaseTime()
def gitCommits = Integer.parseInt('git rev-list --count HEAD'.execute([], project.rootDir).text.trim())
android {
compileSdkVersion 32
buildToolsVersion '32.0.0'
kotlinOptions {
jvmTarget = "11"
}
signingConfigs {
if (project.hasProperty("RELEASE_STORE_FILE")) {
myConfig {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
v1SigningEnabled true
v2SigningEnabled true
}
}
}
defaultConfig {
applicationId "io.legado.app"
minSdkVersion 21
targetSdkVersion 32
versionCode gitCommits
versionName version
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
project.ext.set("archivesBaseName", name + "_" + version)
multiDexEnabled true
javaCompileOptions {
annotationProcessorOptions {
arguments += [
"room.incremental" : "true",
"room.expandProjection": "true",
"room.schemaLocation" : "$projectDir/schemas".toString()
]
}
}
}
buildFeatures {
viewBinding true
}
buildTypes {
release {
buildConfigField "String", "Cronet_Version", "\"$CronetVersion\""
if (project.hasProperty("RELEASE_STORE_FILE")) {
signingConfig signingConfigs.myConfig
}
applicationIdSuffix '.release'
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
buildConfigField "String", "Cronet_Version", "\"$CronetVersion\""
if (project.hasProperty("RELEASE_STORE_FILE")) {
signingConfig signingConfigs.myConfig
}
applicationIdSuffix '.debug'
versionNameSuffix 'debug'
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
android.applicationVariants.all { variant ->
variant.outputs.all {
def flavor = variant.productFlavors[0].name
outputFileName = "${name}_${flavor}_${defaultConfig.versionName}.apk"
}
}
}
flavorDimensions "mode"
productFlavors {
app {
dimension "mode"
manifestPlaceholders = [APP_CHANNEL_VALUE: "app"]
}
google {
dimension "mode"
applicationId "io.legado.play"
manifestPlaceholders = [APP_CHANNEL_VALUE: "google"]
}
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 11
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
sourceSets {
// Adds exported schema location as test app assets.
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
}
tasks.withType(JavaCompile) {
//options.compilerArgs << "-Xlint:unchecked"
}
}
resourcePlaceholders {
files = ['xml/shortcuts.xml']
}
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas")
}
}
dependencies {
coreLibraryDesugaring('com.android.tools:desugar_jdk_libs:1.1.5')
testImplementation('junit:junit:4.13.2')
androidTestImplementation('androidx.test:runner:1.4.0')
androidTestImplementation('androidx.test.espresso:espresso-core:3.4.0')
implementation('androidx.multidex:multidex:2.0.1')
//kotlin
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")
//Kotlin反射
implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version")
//协程
def coroutines_version = '1.6.0'
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version")
//androidX
implementation('androidx.core:core-ktx:1.7.0')
implementation('androidx.appcompat:appcompat:1.4.0')
implementation('androidx.activity:activity-ktx:1.4.0')
implementation('androidx.fragment:fragment-ktx:1.4.0')
implementation('androidx.preference:preference-ktx:1.1.1')
implementation('androidx.constraintlayout:constraintlayout:2.1.2')
implementation('androidx.swiperefreshlayout:swiperefreshlayout:1.1.0')
implementation('androidx.viewpager2:viewpager2:1.0.0')
implementation('com.google.android.material:material:1.4.0')
implementation('com.google.android.flexbox:flexbox:3.0.0')
implementation('com.google.code.gson:gson:2.8.9')
implementation('androidx.webkit:webkit:1.4.0')
implementation('com.jakewharton.timber:timber:5.0.1')
//media
implementation("androidx.media:media:1.4.3")
def exoplayer_version = '2.16.1'
implementation("com.google.android.exoplayer:exoplayer-core:$exoplayer_version")
implementation("com.google.android.exoplayer:extension-okhttp:$exoplayer_version")
//Splitties
def splitties_version = '3.0.0'
implementation("com.louiscad.splitties:splitties-appctx:$splitties_version")
implementation("com.louiscad.splitties:splitties-systemservices:$splitties_version")
implementation("com.louiscad.splitties:splitties-views:$splitties_version")
//lifecycle
def lifecycle_version = '2.4.0'
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycle_version")
//room
def room_version = '2.4.0'
implementation("androidx.room:room-runtime:$room_version")
implementation("androidx.room:room-ktx:$room_version")
kapt("androidx.room:room-compiler:$room_version")
testImplementation("androidx.room:room-testing:$room_version")
//liveEventBus
implementation('io.github.jeremyliao:live-event-bus-x:1.8.0')
//规则相关
implementation('org.jsoup:jsoup:1.14.3')
implementation('com.jayway.jsonpath:json-path:2.6.0')
implementation('cn.wanghaomiao:JsoupXpath:2.5.1')
implementation(project(path: ':epublib'))
//JS rhino
implementation('com.github.gedoor:rhino-android:1.6')
//网络
implementation('com.squareup.okhttp3:okhttp:4.9.3')
implementation(fileTree(dir: 'cronetlib', include: ['*.jar', '*.aar']))
//Glide
implementation('com.github.bumptech.glide:glide:4.12.0')
kapt('com.github.bumptech.glide:compiler:4.12.0')
//webServer
def nanoHttpdVersion = "2.3.1"
implementation("org.nanohttpd:nanohttpd:$nanoHttpdVersion")
implementation("org.nanohttpd:nanohttpd-websocket:$nanoHttpdVersion")
//二维码
implementation('com.github.jenly1314:zxing-lite:2.1.1')
//颜色选择
implementation('com.jaredrummler:colorpicker:1.1.0')
//apache
implementation('org.apache.commons:commons-text:1.9')
//MarkDown
def markwonVersion = "4.6.2"
implementation("io.noties.markwon:core:$markwonVersion")
implementation("io.noties.markwon:image-glide:$markwonVersion")
implementation("io.noties.markwon:ext-tables:$markwonVersion")
implementation("io.noties.markwon:html:$markwonVersion")
//转换繁体
implementation('com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core:0.2.3')
//代码编辑com.github.AmrDeveloper:CodeView已集成到应用内
//epubLib集成到应用内
// LeakCanary
//debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+110
View File
@@ -0,0 +1,110 @@
import java.security.MessageDigest
apply plugin: 'de.undercouch.download'
def BASE_PATH = "https://storage.googleapis.com/chromium-cronet/android/" + CronetVersion + "/Release/cronet/"
def assetsDir = projectDir.toString() + "/src/main/assets"
def libPath = projectDir.toString() + "/cronetlib"
def soPath = projectDir.toString() + "/so"
/**
* 从文件生成MD5
* @param file
* @return
*/
static def generateMD5(final file) {
MessageDigest digest = MessageDigest.getInstance("MD5")
file.withInputStream() { is ->
byte[] buffer = new byte[1024]
int numRead = 0
while ((numRead = is.read(buffer)) > 0) {
digest.update(buffer, 0, numRead)
}
}
return String.format("%032x", new BigInteger(1, digest.digest())).toLowerCase()
}
/**
* 下载Cronet相关的jar
*/
task downloadJar(type: Download) {
src([
BASE_PATH + "cronet_api.jar",
BASE_PATH + "cronet_impl_common_java.jar",
BASE_PATH + "cronet_impl_native_java.jar",
BASE_PATH + "cronet_impl_platform_java.jar",
])
dest libPath
overwrite true
onlyIfModified true
}
/**
* 下载Cronet的arm64-v8a so
*/
task downloadARM64(type: Download) {
src BASE_PATH + "libs/arm64-v8a/libcronet." + CronetVersion + ".so"
dest soPath + "/arm64-v8a.so"
overwrite true
onlyIfModified true
}
/**
* 下载Cronet的armeabi-v7a so
*/
task downloadARMv7(type: Download) {
src BASE_PATH + "libs/armeabi-v7a/libcronet." + CronetVersion + ".so"
dest soPath + "/armeabi-v7a.so"
overwrite true
onlyIfModified true
}
/**
* 下载Cronet的x86_64 so
*/
task downloadX86_64(type: Download) {
src BASE_PATH + "libs/x86_64/libcronet." + CronetVersion + ".so"
dest soPath + "/x86_64.so"
overwrite true
onlyIfModified true
}
/**
* 下载Cronet的x86 so
*/
task downloadX86(type: Download) {
src BASE_PATH + "libs/x86/libcronet." + CronetVersion + ".so"
dest soPath + "/x86.so"
overwrite true
onlyIfModified true
}
/**
* 更新Cronet版本时执行这个task
* 先更改gradle.properties 里面的版本号,然后再执行
* gradlew app:downloadCronet
*/
task downloadCronet() {
dependsOn downloadJar, downloadARM64, downloadARMv7, downloadX86_64, downloadX86
doLast {
StringBuilder sb = new StringBuilder("{")
def files = new File(soPath).listFiles()
for (File file : files) {
println file.name.replace(".so", "")
sb.append("\"").append(file.name.replace(".so", "")).append("\":\"").append(generateMD5(file)).append("\",")
}
sb.append("\"version\":\"").append(CronetVersion).append("\"}")
println sb.toString()
println assetsDir
def f1 = new File(assetsDir + "/cronet.json")
if (!f1.exists()) {
f1.parentFile.mkdirs()
f1.createNewFile()
}
f1.text = sb.toString()
}
}
+151
View File
@@ -0,0 +1,151 @@
{
"project_info": {
"project_number": "453392274790",
"firebase_url": "https://legado-fca69.firebaseio.com",
"project_id": "legado-fca69",
"storage_bucket": "legado-fca69.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:453392274790:android:c4eac14b1410eec5f624a7",
"android_client_info": {
"package_name": "io.legado.app.debug"
}
},
"oauth_client": [
{
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:453392274790:android:c1481c1c3d3f51eff624a7",
"android_client_info": {
"package_name": "io.legado.app.release"
}
},
"oauth_client": [
{
"client_id": "453392274790-trrgennt5njr1lhil1sgtf0ogcgd38fo.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "io.legado.app.release",
"certificate_hash": "fd67dba87b7b761631266f19ddde249054aac5c1"
}
},
{
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:453392274790:android:b891abd2331577dff624a7",
"android_client_info": {
"package_name": "io.legado.play.release"
}
},
"oauth_client": [
{
"client_id": "453392274790-f8sjn6ohs72rg1dvp0pdvk42nkq54p0k.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "io.legado.play.release",
"certificate_hash": "00819ace9891386e535967cbafd6a88f3797bd5b"
}
},
{
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:453392274790:android:b891abd2331577dff624a7",
"android_client_info": {
"package_name": "io.legado.play.debug"
}
},
"oauth_client": [
{
"client_id": "453392274790-f8sjn6ohs72rg1dvp0pdvk42nkq54p0k.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "io.legado.play.debug",
"certificate_hash": "00819ace9891386e535967cbafd6a88f3797bd5b"
}
},
{
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
+231
View File
@@ -0,0 +1,231 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# 混合时不使用大小写混合,混合后的类名为小写
-dontusemixedcaseclassnames
# 指定不去忽略非公共库的类
-dontskipnonpubliclibraryclasses
# 这句话能够使我们的项目混淆后产生映射文件
# 包含有类名->混淆后类名的映射关系
-verbose
# 指定不去忽略非公共库的类成员
-dontskipnonpubliclibraryclassmembers
# 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度
-dontpreverify
# 保留Annotation不混淆
-keepattributes *Annotation*,InnerClasses
# 避免混淆泛型
-keepattributes Signature
# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
# 指定混淆是采用的算法,后面的参数是一个过滤器
# 这个过滤器是谷歌推荐的算法,一般不做更改
-optimizations !code/simplification/cast,!field/*,!class/merging/*
#############################################
#
# Android开发中一些需要保留的公共部分
#
#############################################
# 屏蔽错误Unresolved class name
#noinspection ShrinkerUnresolvedReference
# 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
# 因为这些子类都有可能被外部调用
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
# 保留androidx下的所有类及其内部类
-keep class androidx.** {*;}
# 保留继承的
-keep public class * extends androidx.**
# 保留R下面的资源
-keep class **.R$* {*;}
# 保留本地native方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}
# 保留在Activity中的方法参数是view的方法,
# 这样以来我们在layout中写的onClick就不会被影响
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
# 保留枚举类不被混淆
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 保留我们自定义控件(继承自View)不被混淆
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
# 保留Parcelable序列化类不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# 保留Serializable序列化的类不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
void *(**On*Listener);
}
# webView处理,项目中没有使用到webView忽略即可
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, java.lang.String);
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
# 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用
# 记得proguard-android.txt中一定不要加-dontoptimize才起作用
# 另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制
-assumenosideeffects class android.util.Log {
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
# 保持js引擎调用的java类
-keep class **.analyzeRule.**{*;}
# 保持web类
-keep class **.web.**{*;}
#数据类
-keep class **.data.**{*;}
-dontwarn rx.**
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn org.apache.log4j.lf5.viewer.**
-dontnote org.apache.log4j.lf5.viewer.**
-dontwarn freemarker.**
-dontnote org.python.core.**
-dontwarn com.hwangjr.rxbus.**
-dontwarn okhttp3.**
-dontwarn org.conscrypt.**
-dontwarn com.jeremyliao.liveeventbus.**
-keep class com.google.gson.** { *; }
-keep class com.ke.gson.** { *; }
-keep class com.jeremyliao.liveeventbus.** { *; }
-keep class okhttp3.**{*;}
-keep class okio.**{*;}
-keep class com.hwangjr.rxbus.**{*;}
-keep class org.conscrypt.**{*;}
-keep class android.support.**{*;}
-keep class me.grantland.widget.**{*;}
-keep class de.hdodenhof.circleimageview.**{*;}
-keep class tyrant.explosionfield.**{*;}
-keep class tyrantgit.explosionfield.**{*;}
-keep class freemarker.**{*;}
-keep class com.gyf.barlibrary.** {*;}
##JSOUP
-keep class org.jsoup.**{*;}
-keep class **.xpath.**{*;}
-keep class org.slf4j.**{*;}
-dontwarn org.slf4j.**
-keep class org.codehaus.**{*;}
-dontwarn org.codehaus.**
-keep class com.jayway.**{*;}
-dontwarn com.jayway.**
-keep class com.fasterxml.**{*;}
-keep class javax.swing.**{*;}
-dontwarn javax.swing.**
-keep class java.awt.**{*;}
-dontwarn java.awt.**
-keep class sun.misc.**{*;}
-dontwarn sun.misc.**
-keep class sun.reflect.**{*;}
-dontwarn sun.reflect.**
## Rhino
-keep class javax.script.** { *; }
-keep class com.sun.script.javascript.** { *; }
-keep class org.mozilla.javascript.** { *; }
###EPUB
-dontwarn nl.siegmann.epublib.**
-dontwarn org.xmlpull.**
-keep class nl.siegmann.epublib.**{*;}
-keep class javax.xml.**{*;}
-keep class org.xmlpull.**{*;}
-keep class org.simpleframework.**{*;}
-dontwarn org.simpleframework.xml.**
-keepclassmembers class * {
public <init> (org.json.JSONObject);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Keep all of Cronet API as it's used by the Cronet module.
-keep public class org.chromium.net.* {
!private *;
*;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,26 @@
package io.legado.app
import android.net.Uri
import android.util.Log
import androidx.test.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun testContentProvider() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
Log.d("test",
appContext.contentResolver.query(Uri.parse("content://io.legado.app.api.ReaderProvider/sources/query"),null,null,null,null)
!!.getString(0)
)
}
}
@@ -0,0 +1,50 @@
package io.legado.app
import androidx.room.Room
import androidx.room.migration.Migration
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4
import io.legado.app.data.AppDatabase
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import java.io.IOException
@RunWith(AndroidJUnit4::class)
class MigrationTest {
private val TEST_DB = "migration-test"
private val ALL_MIGRATIONS = arrayOf<Migration>(
)
@Rule
val helper: MigrationTestHelper = MigrationTestHelper(
InstrumentationRegistry.getInstrumentation(),
AppDatabase::class.java.canonicalName,
FrameworkSQLiteOpenHelperFactory()
)
@Test
@Throws(IOException::class)
fun migrateAll() {
// Create earliest version of the database.
helper.createDatabase(TEST_DB, 30).apply {
close()
}
// Open latest version of the database. Room will validate the schema
// once all migrations execute.
Room.databaseBuilder(
InstrumentationRegistry.getInstrumentation().targetContext,
AppDatabase::class.java,
TEST_DB
).addMigrations(*ALL_MIGRATIONS)
.build().apply {
openHelper.writableDatabase
close()
}
}
}
+4
View File
@@ -0,0 +1,4 @@
<resources>
<string name="app_name">阅读·D</string>
<string name="receiving_shared_label">阅读·D·搜索</string>
</resources>
+4
View File
@@ -0,0 +1,4 @@
<resources>
<string name="app_name">legado·D</string>
<string name="receiving_shared_label">legado·D·search</string>
</resources>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">阅读Pro</string>
</resources>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">閱讀Pro</string>
</resources>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">閱讀Pro</string>
</resources>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">legadoPro</string>
</resources>
+465
View File
@@ -0,0 +1,465 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.legado.app">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
android:supportsRtl="true"
android:theme="@style/AppTheme.Light"
tools:ignore="AllowBackup,GoogleAppIndexingWarning,UnusedAttribute">
<!-- 主入口 -->
<activity
android:name=".ui.welcome.WelcomeActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:launchMode="singleTask"
android:resource="@xml/shortcuts" />
</activity>
<!-- 图标1 -->
<activity
android:name=".ui.welcome.Launcher1"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/launcher1">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:launchMode="singleTask"
android:resource="@xml/shortcuts" />
</activity>
<!-- 图标2 -->
<activity
android:name=".ui.welcome.Launcher2"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/launcher2">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:launchMode="singleTask"
android:resource="@xml/shortcuts" />
</activity>
<!-- 图标3 -->
<activity
android:name=".ui.welcome.Launcher3"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/launcher3">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:launchMode="singleTask"
android:resource="@xml/shortcuts" />
</activity>
<!-- 图标4 -->
<activity
android:name=".ui.welcome.Launcher4"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/launcher4">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:launchMode="singleTask"
android:resource="@xml/shortcuts" />
</activity>
<!-- 图标5 -->
<activity
android:name=".ui.welcome.Launcher5"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/launcher5">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:launchMode="singleTask"
android:resource="@xml/shortcuts" />
</activity>
<!-- 图标6 -->
<activity
android:name=".ui.welcome.Launcher6"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/launcher6">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:launchMode="singleTask"
android:resource="@xml/shortcuts" />
</activity>
<!-- 主界面 -->
<activity
android:name=".ui.main.MainActivity"
android:alwaysRetainTaskState="true"
android:launchMode="singleTask" />
<!-- 阅读界面 -->
<activity
android:name=".ui.book.read.ReadBookActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="com.samsung.android.support.REMOTE_ACTION" />
</intent-filter>
<meta-data
android:name="com.samsung.android.support.REMOTE_ACTION"
android:resource="@xml/spen_remote_actions" />
</activity>
<!-- 书籍详情页 -->
<activity
android:name=".ui.book.info.BookInfoActivity"
android:launchMode="singleTop" />
<!-- 书籍信息编辑 -->
<activity
android:name=".ui.book.info.edit.BookInfoEditActivity"
android:launchMode="singleTask" />
<!-- 音频播放界面 -->
<activity
android:name="io.legado.app.ui.book.audio.AudioPlayActivity"
android:launchMode="singleTask" />
<!-- 授权界面 -->
<activity
android:name="io.legado.app.lib.permission.PermissionActivity"
android:theme="@style/Activity.Permission" />
<!-- 二维码扫描 -->
<activity
android:name=".ui.qrcode.QrCodeActivity"
android:launchMode="singleTask" />
<!-- 规则订阅 -->
<activity
android:name=".ui.rss.subscription.RuleSubActivity"
android:launchMode="singleTask" />
<!-- 书源编辑 -->
<activity
android:name=".ui.book.source.edit.BookSourceEditActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize|stateHidden" />
<!-- 订阅源编辑 -->
<activity
android:name=".ui.rss.source.edit.RssSourceEditActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize|stateHidden" />
<!-- 书源编辑 -->
<activity
android:name=".ui.replace.edit.ReplaceEditActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize|stateHidden" />
<!-- 配置界面 -->
<activity
android:name=".ui.config.ConfigActivity"
android:launchMode="singleTask" />
<!-- 搜索界面 -->
<activity
android:name=".ui.book.search.SearchActivity"
android:launchMode="standard" />
<!-- 关于界面 -->
<activity
android:name=".ui.about.AboutActivity"
android:launchMode="singleTask"
android:screenOrientation="behind" />
<!-- 捐赠界面 -->
<activity
android:name=".ui.about.DonateActivity"
android:launchMode="singleTask"
android:screenOrientation="behind" />
<!-- 书源管理 -->
<activity
android:name=".ui.book.source.manage.BookSourceActivity"
android:launchMode="singleTop"
android:screenOrientation="behind" />
<!-- 订阅源管理 -->
<activity
android:name=".ui.rss.source.manage.RssSourceActivity"
android:launchMode="singleTop"
android:screenOrientation="behind" />
<!-- txt目录规则管理 -->
<activity
android:name=".ui.book.local.rule.TxtTocRuleActivity"
android:launchMode="singleTop"
android:screenOrientation="behind" />
<!-- 替换规则界面 -->
<activity
android:name=".ui.replace.ReplaceRuleActivity"
android:launchMode="singleTop"
android:screenOrientation="behind" />
<!-- 书籍管理 -->
<activity
android:name=".ui.book.arrange.ArrangeBookActivity"
android:launchMode="singleTop"
android:screenOrientation="behind" />
<!-- 书源调试 -->
<activity
android:name=".ui.book.source.debug.BookSourceDebugActivity"
android:launchMode="singleTop"
android:screenOrientation="behind" />
<!-- 目录 -->
<activity
android:name=".ui.book.toc.TocActivity"
android:launchMode="singleTop"
android:screenOrientation="behind" />
<!-- 正文搜索 -->
<activity
android:name=".ui.book.searchContent.SearchContentActivity"
android:launchMode="singleTop"
android:screenOrientation="behind" />
<!-- RSS条目 -->
<activity
android:name=".ui.rss.article.RssSortActivity"
android:launchMode="singleTop" />
<!-- RSS阅读 -->
<activity
android:name=".ui.rss.read.ReadRssActivity"
android:configChanges="orientation|screenSize"
android:hardwareAccelerated="true"
android:launchMode="singleTop" />
<!-- 导入书籍 -->
<activity
android:name=".ui.book.local.ImportBookActivity"
android:launchMode="singleTop" />
<!-- 发现界面 -->
<activity
android:name=".ui.book.explore.ExploreShowActivity"
android:launchMode="singleTop" />
<!-- 订阅源调试 -->
<activity
android:name=".ui.rss.source.debug.RssSourceDebugActivity"
android:launchMode="singleTop" />
<!-- Rss收藏 -->
<activity
android:name=".ui.rss.favorites.RssFavoritesActivity"
android:launchMode="singleTop" />
<!-- 缓存界面 -->
<activity
android:name=".ui.book.cache.CacheActivity"
android:launchMode="singleTop" />
<!-- WebView界面 -->
<activity
android:name=".ui.browser.WebViewActivity"
android:launchMode="standard" />
<!-- 书源登录 -->
<activity
android:name="io.legado.app.ui.login.SourceLoginActivity"
android:configChanges="orientation|screenSize"
android:hardwareAccelerated="true"
android:theme="@style/AppTheme.Transparent" />
<!-- 阅读记录 -->
<activity
android:name=".ui.about.ReadRecordActivity"
android:configChanges="orientation|screenSize"
android:hardwareAccelerated="true" />
<!-- 选择文件 -->
<activity
android:name=".ui.document.HandleFileActivity"
android:configChanges="orientation|screenSize"
android:hardwareAccelerated="true"
android:theme="@style/AppTheme.Transparent" />
<!-- 文字处理 -->
<activity
android:name=".receiver.SharedReceiverActivity"
android:exported="true"
android:label="@string/receiving_shared_label"
android:theme="@style/AppTheme.Transparent">
<intent-filter>
<action android:name="android.intent.action.PROCESS_TEXT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<!-- 一键导入 -->
<activity
android:name=".ui.association.OnLineImportActivity"
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="true"
android:theme="@style/AppTheme.Transparent">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="legado" />
<data android:scheme="yuedu" />
</intent-filter>
</activity>
<!-- 打开文件 -->
<activity
android:name=".ui.association.FileAssociationActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/AppTheme.Transparent">
<!-- VIEW (Open with) action -->
<!-- Works when an app knows the media type of a file, e.g. Gmail or Chrome. -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="app" />
<data android:scheme="content" />
<data android:scheme="file" />
<!-- text -->
<data android:mimeType="text/plain" />
<!-- json -->
<data android:mimeType="application/json" />
<!-- EPUB -->
<data android:mimeType="application/epub+zip" />
</intent-filter>
<!-- Works when an app doesn't know the media type, e.g. Dropbox -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="*" />
<data android:scheme="app" />
<data android:scheme="content" />
<data android:scheme="file" />
<!-- This media type is necessary, otherwise it won't match on the file extension -->
<data android:mimeType="*/*" />
<!--TXT-->
<data android:pathPattern=".*\\.txt" />
<data android:pathPattern=".*\\.TXT" />
<!--JSON-->
<data android:pathPattern=".*\\.json" />
<data android:pathPattern=".*\\.JSON" />
<!-- EPUB -->
<data android:pathPattern=".*\\.epub" />
<data android:pathPattern=".*\\.EPUB" />
</intent-filter>
</activity>
<service android:name=".service.CheckSourceService" />
<service android:name=".service.CacheBookService" />
<service android:name=".service.WebService" />
<service
android:name=".service.WebTileService"
android:exported="true"
android:icon="@drawable/ic_web_service_noti"
android:label="legado Web Service"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<service android:name=".service.TTSReadAloudService" />
<service android:name=".service.HttpReadAloudService" />
<service android:name=".service.AudioPlayService" />
<service android:name=".service.DownloadService" />
<receiver
android:name=".receiver.MediaButtonReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
<provider
android:name=".api.ReaderProvider"
android:authorities="${applicationId}.readerProvider"
android:enabled="true"
android:exported="true"
tools:ignore="ExportedContentProvider" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<meta-data
android:name="channel"
android:value="${APP_CHANNEL_VALUE}" />
</application>
<queries>
<intent>
<action android:name="android.intent.action.TTS_SERVICE" />
</intent>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT" />
<data android:mimeType="text/plain" />
</intent>
</queries>
</manifest>
+284
View File
@@ -0,0 +1,284 @@
OGN5dS5jb20=
c2cwMC54eXo=
aXRyYWZmaWNuZXQuY29t
eGlhb3FpYW5nNTIw
MTIzeGlhb3FpYW5n
eGlhb3FpYW5neHM=
eGlhb3FpYW5nNTIw
MzM1eHM=
eGN4czk=
eGN4czUyMA==
c2h1YmFvYW4=
c2h1YmFvd2FuZzEyMw==
c2h1YmFvYW4=
aGFpdGFuZzEyMw==
eXV6aGFpd3VsYQ==
cG8xOA==
Ymwtbm92ZWw=
NXRucw==
c2hhb3NodWdl
amluamlzaHV3dQ==
NDJ3Zw==
eWlxdXNodQ==
c2h1YmFvd2FuZzEyMw==
M2hlYmFv
MzNoZWJhbw==
bHVvcWl1enc=
bXlzaHVnZQ==
c3NzeHN3
eWl0ZQ==
Y3Vpd2VpanV1
Y3Vpd2VpanV4cw==
Y3Vpd2VpanV4
eGlhb3FpYW5nd3g=
YXN6dw==
YXN6dzY=
c2FuaGFveHM=
ODdzaHV3dQ==
NDh3eA==
bG9uZ3Rlbmcy
NnF3eA==
bG9uZ3Rlbmd4cw==
aGF4ZHU=
M3R3eA==
aGF4d3g1
NjZsZXdlbg==
eGJhbnpodQ==
aGR5cA==
ZHliejk=
ZGl5aWJhbnpodTk=
ZGl5aWJhbnpodQ==
ZGl5aWJhbnpodTc=
YnoyMjI=
d29kZWFwaTAwMQ==
dGFuZ3poZWthbg==
YmF4aWFueHM=
eGlhb3NodW9zaGVuemhhbg==
ZGFtb2tl
emh3ZW5wZw==
eXV6aGFpZ2U=
d21wOA==
OXhpYW53ZW4=
bmFucmVudmlw
cmV5b28=
eWZ4aWFvc2h1b2U=
c2Fuaml1enc=
N3Fpbmc3
cWR4aWFvc2h1bw==
Y2hpbmVzZXpq
MzlzaHViYW8=
a3l4czU=
NTZtcw==
bml1c2hh
bWt4czY=
MjIyMjJ4cw==
OTVkdXNodQ==
YmFuemh1MjI=
d3JsdHh0
dHVkb3V0eHQ=
cm5neHM=
OTl3ZW5rdQ==
bGFvc2lqaXhz
ZnVzaHV6aGFpMQ==
cG8xOA==
czUyMTc=
c2FuaGFveHM=
NTJrc2h1
NDhyeA==
ZWNub3ZlbA==
bGllaHVvenc=
eGlhb3FpYW5nd3g=
NTJrc2h1
NDh3eA==
NTJrc2h1
MDB1aQ==
MDFieg==
c2h1YmFvMQ==
ZG54aWFvc2h1b2E=
am5zaHViYQ==
MThzaHV3dQ==
bGV4cw==
MzM1eHM=
dXB1
ZnVndW9kdQ==
ODB0eHQ=
YWFyZWFk
eWlkdWR1MQ==
YmFuemh1d2FuZw==
cWloYW9xaWhhbw==
OHhpYW54cw==
amluamlzaHV3dQ==
d21wOA==
ZXl1c2h1d3U=
NTB4c2Y=
aGF4d3g1
cG93YW5qdWFu
d2luMTBjaXR5
eWV5ZXhzdw==
bXlzaHVnZQ==
eGlhbmd0eHN3
Y3Vpd2VpanV4
MzY2eHN3
aHVheXVld2Vua3U=
eW91ZGlhbmxlbg==
c291Nzg=
bGFucm91Mg==
cXFib29r
eW91d3V4cw==
cnVpbGlzYWxl
MzY1bXd3
ZnV3ZW5o
bGVzYmw=
YXd1Ym9vaw==
bGl5dXhpYW5nMjAyMA==
OTJwb3Bv
ZnVzaHV0dWFu
ODhkYW5tZWk=
ZG14cw==
eXVsaW56aGFueWU=
M2hlYmFv
eGd1YWd1YXhz
ZGl5aWJhbnpodTY=
aXJlYWR4cw==
c2h1YmFvOTY=
ZGl5aWJhbnpodTU1NQ==
c2Fuaml1enc=
N3Fpbmc3
NjZsZXdlbg==
a3l4czU=
MjIyMjJ4cw==
c2hhb3NodWdl
amlsaW41NQ==
bWt4czY=
amluc2h1bG91
eGlhbndhbmdz
eWlkdWR1
cWR0eHQ=
MTZib29rMQ==
am1zaHV3dQ==
MzY2eHN3
ZHliejk=
c2hvdWRhOA==
ZnlxMTg=
eWlzaHVn
eXV6aGFpd3VsYQ==
MTFiYW56aHU=
MTIzeGlhb3FpYW5n
ZGl5aWJhbnpodTk=
ZGl5aWJhbnpodQ==
MzY2eHN3
ODdzaHV3dQ==
NnF3eA==
emhlbmh1bnhpYW9zaHVv
bG9uZ3Rlbmc1Mg==
eGlueGluZ3hpYW5nemhpZmE=
ZHliejk=
ZHVvemhla2Fu
MTIzeGlhb3FpYW5n
MzM1eHM=
am1zaHV3dQ==
c2hhb3NodWdl
bGF3ZW54cw==
cnVzaHV3dQ==
MzY2eHN3
NTB4c2Y=
bGV3ZW41NQ==
aGFpdGFuZzEyMw==
aGViYW81MjA=
bHVvcWl1enc=
c3NzeHN3
c2h1c2h1d3V4cw==
cm5neHM=
cWR4aWFvc2h1bw==
dHl1ZQ==
Y2hlNDM=
bG9uZ3Rlbmcy
amZ5eHNo
aGV0dTI=
bGFvc2lqaXhz
bG9uZ3Rlbmd4cw==
bGllaHVvenc=
c2h1YmFvYW4=
eHNodW9zaHVv
NTIxZGFubWVp
YmFuemh1MjI=
cWtzaHU=
eWZ4aWFvc2h1b2U=
a3lnc28=
c2h1bG91YmE=
NXRucw==
N3Fpbmc3
bWlhb2R1NQ==
eXVzaHV3ZW4=
YWFyZWFk
cXRzaHU=
MTdzaHV3dQ==
c2h1YmFvMnM=
YnowMDE=
ZGFtb2dl
MTMxdGI=
aXhpYW9z
bXlzaHVnZQ==
OXhpYW53ZW4=
ZHVvemhla2Fu
MTIwdw==
c2h1c2h1d3U1MjA=
c2h1YmFvMnM=
YWd4c3c=
OTR4c3c=
cG8xOA==
eWFvY2hpeHM=
eGlhb3FpYW5neHM=
Ym9va2Js
c2Fuaml1eHM=
d29kZXNodWJhbw==
em9uZ2NhaXhpYW9zaHVvMg==
OWI4OTEzOTRkZjVi
MThub3ZlbA==
YWFib29r
YjF0eHQ=
eXVjYWl6dw==
Yzl0eHQ=
ZGl5aWJhbnpodTU1NQ==
MzBtYw==
eGlueXVzaHV3dQ==
c2h1YmFvd2FuZzEyMw==
YWd4cw==
YmlxdWdlbmw=
c2hpcWlzaHV3dQ==
c2lsdWtl
ZGl5aWJhbnpodTg=
ZGl5aWJhbnpodTk=
aGV0dW54cw==
OTl3ZW5rdQ==
aGFpdGFuZ3NodXd1
OTd5ZA==
eXV6aGFpd3UxMQ==
Y3Vpd2VpanV4cw==
Y2JpcXU=
NTIxZGFubWVp
c2h1YmFvMzM=
c2FuaGFvMQ==
dGlhbm1lbmd3ZW5rdQ==
eXVzaHV3dTUyMA==
c2h1YmFvMjIy
c2h1YmFvd2FuZzEyMw==
eXVib29r
Y2JpcXU=
MWxld2Vu
MTV4c3c=
eG5jd3h3
c2h1YmFvd2FuZzEyMw==
c2FuaGFveHM=
eXV3YW5nc2hl
YmlxdXRz
bGFtZWl4cw==
eGJhbnpodQ==
cWR4aWFvc2h1bw==
bWh0bGE=
OTl3ZW5rdQ==
eGlhb3FpYW5nNTIw
dGlhbm1lbmd3ZW5rdQ==
YWlmdXNodQ==
bWlhb2R1NQ==
bWlmZW5neHM=
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

+1
View File
@@ -0,0 +1 @@
{"arm64-v8a":"690c212d9bbad4b09b9e1ba450b273bb","armeabi-v7a":"4dbb88e5229abef7d84138218772f872","x86":"3f2421e040147da48abb07cfc6c7c87e","x86_64":"730a71ef4f03a27d1c8c8a77e7d09ff5","version":"96.0.4664.104"}
@@ -0,0 +1,48 @@
[
{
"bookSourceComment": "",
"bookSourceGroup": "听书",
"bookSourceName": "消消乐听书",
"bookSourceType": 1,
"bookSourceUrl": "https://www.kaixin7days.com",
"customOrder": 0,
"enabled": true,
"enabledExplore": true,
"exploreUrl": "@js:var header = JSON.parsesource.getLoginHeader()\nvar json = ''\nvar j = null\nif (header != null) {\n json = java.connect('https://www.kaixin7days.com/book-service/bookMgt/getBookCategroy,{\"method\":\"POST\",\"body\":{}}', header).body()\n j = JSON.parse(json)\n}\nif (j == null || j.statusCode != 200) {\n json = java.connect('https://www.kaixin7days.com/visitorLogin,{\"method\":\"POST\", \"body\":{} }').body()\n j = JSON.parse(json)\n var accessToken = {\n Authorization: 'Bearer ' + j.content.accessToken\n }\n header = JSON.stringify(accessToken)\n source.putLoginHeader(header)\n json = java.connect('https://www.kaixin7days.com/book-service/bookMgt/getBookCategroy,{\"method\":\"POST\",\"body\":{} }', header).body()\n j = JSON.parse(json)\n}\nvar fls = j.content\nvar fx = []\nfor (var i = 0; i < fls.length; i++) {\n fx.push({\n title: fls[i].categoryName,\n url: '/book-service/bookMgt/getAllBookByCategroyId,{\"method\":\"POST\",\"body\":{\"categoryIds\": \"' + fls[i].associationCategoryIDs + '\",\"pageNum\": {{page}},\"pageSize\": 100}}'\n })\n}\nJSON.stringify(fx)",
"searchUrl": "https://www.kaixin7days.com/book-service/bookMgt/findBookName,{\"method\":\"POST\",\"body\":{\"title\": \"searchKey\",\"pageNum\": {{searchPage}},\"pageSize\": 100}}",
"lastUpdateTime": 1630656684531,
"loginCheckJs": "var strRes = result\nvar c = JSON.parse(result.body())\nif (c.statusCode == 301) {\n var loginInfo = source.getLoginInfo()\n var dl = null\n if (loginInfo) {\n dl = java.connect('https://www.kaixin7days.com/login,{\"method\":\"POST\",\"body\":' + loginInfo + '}').body()\n } else {\n dl = java.connect('https://www.kaixin7days.com/visitorLogin,{\"method\":\"POST\",\"body\":{}}').body()\n }\n c = JSON.parse(dl)\n var accessToken = {\n Authorization: \"Bearer \" + c.content.accessToken\n }\n var header = JSON.stringify(accessToken)\n source.putLoginHeader(header)\n strRes = java.connect(url, header)\n}\nstrRes",
"loginUi": "[{\"name\": \"telephone\",\"type\": \"text\"},{\"name\": \"password\",\"type\": \"password\"},{\"name\": \"注册\",\"type\": \"button\",\"action\": \"http://www.yooike.com/xiaoshuo/#/register?title=%E6%B3%A8%E5%86%8C\"}]",
"loginUrl": "var loginInfo = source.getLoginInfo()\nvar json = java.connect('https://www.kaixin7days.com/login,{\"method\":\"POST\",\"body\":' + loginInfo + '}').body()\nvar loginRes = JSON.parse(json)\nvar header = null\nif (loginRes.statusCode == 200) {\n var accessToken = {\n Authorization: \"Bearer \" + loginRes.content.accessToken\n }\n header = JSON.stringify(accessToken)\n source.putLoginHeader(header)\n}\nheader",
"respondTime": 180000,
"ruleBookInfo": {},
"ruleContent": {
"content": "",
"payAction": "var header = JSON.parse(source.getLoginHeader()); var bookId = book.getVariableMap().get('bookId');var chapterId = java.get('chapterId');\n'http://www.shuidi.online/?name=' + book.getName() + '&type=2&cover=' + book.getCoverUrl() + '&chapterId=' + chapterId + '&chapter=203&allNumber=' + book.getTotalChapterNum() + '&bookId=' + bookId + '&chapterIds=' + chapterId + '&number=' + chapter.getIndex() + '&accessToken=' + header.Authorization.substring(7) + '#/pay'"
},
"ruleExplore": {
"author": "$.author",
"bookList": "$.content.content",
"bookUrl": "$.id@js:java.put('bookId', result);'https://www.kaixin7days.com/book-service/bookMgt/getAllChapterByBookId,{ \"method\": \"POST\",\"body\": {\"bookId\": \"'+result+'\",\"pageNum\": \"1\",\"pageSize\": \"10000\"} }'",
"coverUrl": "$.cover@js:var cover = JSON.parse(result);'https://www.shuidi.online/fileMgt/getPicture?filePath='+cover.storeFilePath",
"intro": "$.desc",
"lastChapter": "$.newestChapter",
"name": "$.title"
},
"ruleSearch": {
"author": "$.author",
"bookList": "$.content.content",
"bookUrl": "$.id@js:java.put('bookId', result);'https://www.kaixin7days.com/book-service/bookMgt/getAllChapterByBookId,{ \"method\": \"POST\",\"body\": {\"bookId\": \"'+result+'\",\"pageNum\": \"1\",\"pageSize\": \"10000\"} }'",
"coverUrl": "$.cover@js:var cover = JSON.parse(result);'https://www.shuidi.online/fileMgt/getPicture?filePath='+cover.storeFilePath",
"intro": "$.desc",
"lastChapter": "$.newestChapter",
"name": "$.title"
},
"ruleToc": {
"chapterList": "$.content.content",
"chapterName": "$.chapterTitle",
"chapterUrl": "$.id@js:java.put('chapterId', result);'https://www.shuidi.online/fileMgt/getAudioByChapterId?bookId=' + java.get('bookId') + '&chapterId=' + result + \"&pageNum=1&pageSize=50&keyId={{var header = JSON.parse(source.getLoginHeader());var keyId = '1632746188011002';var ks = java.md5Encode(keyId + java.get('chapterId') + header.Authorization);keyId + '&keySecret=' + ks}\" + '}'"
},
"weight": 0
}
]
@@ -0,0 +1,5 @@
{
"UploadUrl": "http://sy.miaogongzi.cc/shuyuan,{\"method\":\"POST\",\"body\": {\"file\": \"fileRequest\"},\"type\": \"multipart/form-data\"}",
"DownloadUrlRule": "$.data@js:if (result == '') \n '' \n else \n 'https://shuyuan.miaogongzi.cc/shuyuan/' + result",
"summary": "有效期2天"
}
@@ -0,0 +1,30 @@
[
{
"id": -100,
"name": "1.百度",
"url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4127&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=11&vol=5&aue=6&pit=3&_res_tag_=audio\"\n}",
"contentType": "audio/wav"
},
{
"id": -29,
"name": "2.阿里云语音",
"url": "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts,{\"method\": \"POST\",\"body\": {\"appkey\":\"{{source.getLoginInfoMap().get('AppKey')}}\",\"text\":\"{{speakText}}\",\"format\":\"mp3\",\"volume\":100,\"speech_rate\":{{String((speakSpeed) * 20 - 400)}} }}",
"contentType": "audio/mpeg",
"loginUrl": "var loginInfo = source.getLoginInfoMap();\nvar accessKeyId = loginInfo.get('AccessKeyId');\nvar accessKeySecret = loginInfo.get('AccessKeySecret');\nvar timestamp = java.timeFormatUTC(new Date().getTime(), \"yyyy-MM-dd'T'HH:mm:ss'Z'\", 0);\nvar aly = new JavaImporter(Packages.javax.crypto.Mac, Packages.javax.crypto.spec.SecretKeySpec, Packages.javax.xml.bind.DatatypeConverter, Packages.java.net.URLEncoder, Packages.java.lang.String, Packages.android.util.Base64);\nwith (aly) {\n function percentEncode(value) {\n return URLEncoder.encode(value, \"UTF-8\").replace(\"+\", \"%20\")\n .replace(\"*\", \"%2A\").replace(\"%7E\", \"~\")\n }\n\n function sign(stringToSign, accessKeySecret) {\n var mac = Mac.getInstance('HmacSHA1');\n mac.init(new SecretKeySpec(String(accessKeySecret + '&').getBytes(\"UTF-8\"), \"HmacSHA1\"));\n var signData = mac.doFinal(String(stringToSign).getBytes(\"UTF-8\"));\n var signBase64 = Base64.encodeToString(signData, Base64.NO_WRAP);\n var signUrlEncode = percentEncode(signBase64);\n return signUrlEncode;\n }\n}\nvar query = 'AccessKeyId=' + accessKeyId + '&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&SignatureMethod=HMAC-SHA1&SignatureNonce=' + java.randomUUID() + '&SignatureVersion=1.0&Timestamp=' + percentEncode(timestamp) + '&Version=2019-02-28';\nvar signStr = sign('GET&' + percentEncode('/') + '&' + percentEncode(query), accessKeySecret);\nvar queryStringWithSign = \"Signature=\" + signStr + \"&\" + query;\nvar body = java.ajax('http://nls-meta.cn-shanghai.aliyuncs.com/?' + queryStringWithSign)\nvar res = JSON.parse(body)\nif (res.Message) {\n throw new Error(res.Message)\n}\nvar header = { \"X-NLS-Token\": res.Token.Id };\nsource.putLoginHeader(JSON.stringify(header))",
"loginUi": [
{
"name": "AppKey",
"type": "text"
},
{
"name": "AccessKeyId",
"type": "text"
},
{
"name": "AccessKeySecret",
"type": "text"
}
],
"loginCheckJs": "var response = result;\nif (response.headers().get(\"Content-Type\") != \"audio/mpeg\") {\n var body = JSON.parse(response.body().string())\n if (body.status == 40000001) {\n source.login()\n java.getHeaderMap().putAll(source.getHeaderMap(true))\n response = java.getResponse()\n } else {\n throw body.message\n }\n}\nresponse"
}
]
@@ -0,0 +1,107 @@
[
{
"bgStr": "#ffc0edc6",
"bgStrEInk": "#FFFFFF",
"bgStrNight": "#000000",
"bgType": 0,
"bgTypeEInk": 0,
"bgTypeNight": 0,
"darkStatusIcon": true,
"darkStatusIconEInk": true,
"darkStatusIconNight": false,
"footerMode": 0,
"footerPaddingBottom": 10,
"footerPaddingLeft": 13,
"footerPaddingRight": 17,
"footerPaddingTop": 0,
"headerMode": 0,
"headerPaddingBottom": 0,
"headerPaddingLeft": 19,
"headerPaddingRight": 16,
"headerPaddingTop": 10,
"letterSpacing": 0,
"lineSpacingExtra": 10,
"name": "微信读书",
"paddingBottom": 4,
"paddingLeft": 22,
"paddingRight": 22,
"paddingTop": 5,
"pageAnim": 3,
"pageAnimEInk": 3,
"paragraphIndent": "  ",
"paragraphSpacing": 6,
"showFooterLine": true,
"showHeaderLine": true,
"textBold": 0,
"textColor": "#ff0b0b0b",
"textColorEInk": "#000000",
"textColorNight": "#ADADAD",
"textSize": 24,
"tipColor": -10461088,
"tipFooterLeft": 7,
"tipFooterMiddle": 0,
"tipFooterRight": 6,
"tipHeaderLeft": 1,
"tipHeaderMiddle": 0,
"tipHeaderRight": 2,
"titleBottomSpacing": 0,
"titleMode": 0,
"titleSize": 4,
"titleTopSpacing": 0
},
{
"name": "预设1",
"bgStr": "#FFFFFF",
"bgStrNight": "#000000",
"textColor": "#000000",
"textColorNight": "#FFFFFF",
"bgType": 0,
"bgTypeNight": 0,
"darkStatusIcon": true,
"darkStatusIconNight": false
},
{
"name": "预设2",
"bgStr": "#DDC090",
"bgStrNight": "#3C3F43",
"textColor": "#3E3422",
"textColorNight": "#DCDFE1",
"bgType": 0,
"bgTypeNight": 0,
"darkStatusIcon": true,
"darkStatusIconNight": false
},
{
"name": "预设3",
"bgStr": "#C2D8AA",
"bgStrNight": "#3C3F43",
"textColor": "#596C44",
"textColorNight": "#88C16F",
"bgType": 0,
"bgTypeNight": 0,
"darkStatusIcon": false,
"darkStatusIconNight": false
},
{
"name": "预设4",
"bgStr": "#DBB8E2",
"bgStrNight": "#3C3F43",
"textColor": "#68516C",
"textColorNight": "#F6AEAE",
"bgType": 0,
"bgTypeNight": 0,
"darkStatusIcon": false,
"darkStatusIconNight": false
},
{
"name": "预设5",
"bgStr": "#ABCEE0",
"bgStrNight": "#3C3F43",
"textColor": "#3D4C54",
"textColorNight": "#90BFF5",
"bgType": 0,
"bgTypeNight": 0,
"darkStatusIcon": false,
"darkStatusIconNight": false
}
]
@@ -0,0 +1,42 @@
[
{
"customOrder": 1,
"enableJs": true,
"enabled": true,
"singleUrl": true,
"sourceGroup": "legado",
"sourceIcon": "https://cdn.jsdelivr.net/gh/gedoor/legado@master/app/src/main/res/mipmap-hdpi/ic_launcher.png",
"sourceName": "使用说明",
"sourceUrl": "https://www.yuque.com/legado"
},
{
"customOrder": 2,
"enableJs": true,
"enabled": true,
"singleUrl": true,
"sourceGroup": "legado",
"sourceIcon": "http://mmbiz.qpic.cn/mmbiz_png/hpfMV8hEuL2eS6vnCxvTzoOiaCAibV6exBzJWq9xMic9xDg3YXAick87tsfafic0icRwkQ5ibV0bJ84JtSuxhPuEDVquA/0?wx_fmt=png",
"sourceName": "小说拾遗",
"sourceUrl": "snssdk1128://user/profile/562564899806367"
},
{
"customOrder": 3,
"enableJs": true,
"enabled": true,
"singleUrl": true,
"sourceGroup": "legado",
"sourceIcon": "https://Cloud.miaogongzi.site/images/icon.png",
"sourceName": "Meow云",
"sourceUrl": "https://pan.miaogongzi.net"
},
{
"customOrder": 4,
"enableJs": true,
"enabled": true,
"singleUrl": true,
"sourceGroup": "legado",
"sourceIcon": "https://cdn.jsdelivr.net/gh/gedoor/legado@master/app/src/main/res/mipmap-hdpi/ic_launcher.png",
"sourceName": "烏雲净化",
"sourceUrl": "https://www.lanzoux.com/b0bw8jwoh"
}
]
@@ -0,0 +1,26 @@
[
{
"themeName": "典雅蓝",
"isNightTheme": false,
"primaryColor": "#03A9F4",
"accentColor": "#AD1457",
"backgroundColor": "#F5F5F5",
"bottomBackground": "#EEEEEE"
},
{
"themeName": "黑白",
"isNightTheme": true,
"primaryColor": "#303030",
"accentColor": "#E0E0E0",
"backgroundColor": "#424242",
"bottomBackground": "#424242"
},
{
"themeName": "A屏黑",
"isNightTheme": true,
"primaryColor": "#000000",
"accentColor": "#FFFFFF",
"backgroundColor": "#000000",
"bottomBackground": "#000000"
}
]
@@ -0,0 +1,128 @@
[
{
"id": -1,
"enable": true,
"name": "目录(去空白)",
"rule": "(?<=[ \\s])(?:序章|序言|卷首语|扉页|楔子|正文(?!完|结)|终章|后记|尾声|番外|第?\\s{0,4}[\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+?\\s{0,4}(?:章|节(?!课)|卷|集(?![合和])|部(?![分赛游])|篇(?!张))).{0,30}$",
"serialNumber": 0
},
{
"id": -2,
"enable": true,
"name": "目录",
"rule": "^[  \\t]{0,4}(?:序章|序言|卷首语|扉页|楔子|正文(?!完|结)|终章|后记|尾声|番外|第?\\s{0,4}[\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+?\\s{0,4}(?:章|节(?!课)|卷|集(?![合和])|部(?![分赛游])|篇(?!张))).{0,30}$",
"serialNumber": 1
},
{
"id": -3,
"enable": false,
"name": "目录(匹配简介)",
"rule": "(?<=[ \\s])(?:(?:内容|文章)?简介|文案|前言|序章|序言|卷首语|扉页|楔子|正文(?!完|结)|终章|后记|尾声|番外|第?\\s{0,4}[\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+?\\s{0,4}(?:章|节(?!课)|卷|集(?![合和])|部(?![分赛游])|回(?![合来事去])|场(?![和合比电是])|篇(?!张))).{0,30}$",
"serialNumber": 2
},
{
"id": -4,
"enable": false,
"name": "目录(古典、轻小说备用)",
"rule": "^[  \\t]{0,4}(?:序章|楔子|正文(?!完|结)|终章|后记|尾声|番外|第?\\s{0,4}[\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+?\\s{0,4}(?:章|节(?!课)|卷|集(?![合和])|部(?![分赛游])|回(?![合来事去])|场(?![和合比电是])|话|篇(?!张))).{0,30}$",
"serialNumber": 3
},
{
"id": -5,
"enable": false,
"name": "数字(纯数字标题)",
"rule": "(?<=[ \\s])\\d+\\.?[  \\t]{0,4}$",
"serialNumber": 4
},
{
"id": -6,
"enable": true,
"name": "数字 分隔符 标题名称",
"rule": "^[  \\t]{0,4}\\d{1,5}[:,. 、_—\\-].{1,30}$",
"serialNumber": 5
},
{
"id": -7,
"enable": true,
"name": "大写数字 分隔符 标题名称",
"rule": "^[  \\t]{0,4}(?:序章|序言|卷首语|扉页|楔子|正文(?!完|结)|终章|后记|尾声|番外|[〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8})[ 、_—\\-].{1,30}$",
"serialNumber": 6
},
{
"id": -8,
"enable": true,
"name": "正文 标题/序号",
"rule": "^[  \\t]{0,4}正文[  ]{1,4}.{0,20}$",
"serialNumber": 7
},
{
"id": -9,
"enable": true,
"name": "Chapter/Section/Part/Episode 序号 标题",
"rule": "^[  \\t]{0,4}(?:[Cc]hapter|[Ss]ection|[Pp]art|PART|[Nn][oO]\\.|[Ee]pisode|(?:内容|文章)?简介|文案|前言|序章|楔子|正文(?!完|结)|终章|后记|尾声|番外)\\s{0,4}\\d{1,4}.{0,30}$",
"serialNumber": 8
},
{
"id": -10,
"enable": false,
"name": "Chapter(去简介)",
"rule": "^[  \\t]{0,4}(?:[Cc]hapter|[Ss]ection|[Pp]art|PART|[Nn][Oo]\\.|[Ee]pisode)\\s{0,4}\\d{1,4}.{0,30}$",
"serialNumber": 9
},
{
"id": -11,
"enable": true,
"name": "特殊符号 序号 标题",
"rule": "(?<=[\\s ])[【〔〖「『〈[\\[](?:第|[Cc]hapter)[\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,10}[章节].{0,20}$",
"serialNumber": 10
},
{
"id": -12,
"enable": false,
"name": "特殊符号 标题(成对)",
"rule": "(?<=[\\s ]{0,4})(?:[\\[〈「『〖〔《(【\\(].{1,30}[\\)】)》〕〗』」〉\\]]?|(?:内容|文章)?简介|文案|前言|序章|楔子|正文(?!完|结)|终章|后记|尾声|番外)[  ]{0,4}$",
"serialNumber": 11
},
{
"id": -13,
"enable":true,
"name": "特殊符号 标题(单个)",
"rule": "(?<=[\\s ]{0,4})(?:[☆★✦✧].{1,30}|(?:内容|文章)?简介|文案|前言|序章|楔子|正文(?!完|结)|终章|后记|尾声|番外)[  ]{0,4}$",
"serialNumber": 12
},
{
"id": -14,
"enable": true,
"name": "章/卷 序号 标题",
"rule": "^[ \\t ]{0,4}(?:(?:内容|文章)?简介|文案|前言|序章|序言|卷首语|扉页|楔子|正文(?!完|结)|终章|后记|尾声|番外|[卷章][\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8})[  ]{0,4}.{0,30}$",
"serialNumber": 13
},
{
"id": -15,
"enable":false,
"name": "顶格标题",
"rule": "^\\S.{1,20}$",
"serialNumber": 14
},
{
"id": -16,
"enable":false,
"name": "双标题(前向)",
"rule": "(?m)(?<=[ \\t ]{0,4})第[\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}章.{0,30}$(?=[\\s ]{0,8}第[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}章)",
"serialNumber": 15
},
{
"id": -17,
"enable":false,
"name": "双标题(后向)",
"rule": "(?m)(?<=[ \\t ]{0,4}第[\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}章.{0,30}$[\\s ]{0,8})第[\\d零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}章.{0,30}$",
"serialNumber": 16
},
{
"id":-18,
"enable": true,
"name": "标题 特殊符号 序号",
"rule": "^.{1,20}[(][\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}[)][  \t]{0,4}$",
"serialNumber": 17
}
]
+16
View File
@@ -0,0 +1,16 @@
# 免责声明(Disclaimer
* 阅读是一款解析指定规则并获取内容的工具,为广大网络文学爱好者提供一种方便、快捷舒适的试读体验。
* 当您搜索一本书的时,阅读会您所使用的规则将该书的书名以关键词的形式提交到各个第三方网络文学网站。
各第三方网站返回的内容与阅读无关,阅读对其概不负责,亦不承担任何法律责任。
任何通过使用阅读而链接到的第三方网页均系他人制作或提供,您可能从第三方网页上获得其他服务,阅读对其合法性概不负责,亦不承担任何法律责任。
第三方搜索引擎结果根据您提交的书名自动搜索获得并提供试读,不代表阅读赞成或被搜索链接到的第三方网页上的内容或立场。
您应该对使用搜索引擎的结果自行承担风险。
* 阅读不做任何形式的保证:不保证第三方搜索引擎的搜索结果满足您的要求,不保证搜索服务不中断,不保证搜索结果的安全性、正确性、及时性、合法性。
因网络状况、通讯线路、第三方网站等任何原因而导致您不能正常使用阅读,阅读不承担任何法律责任。
阅读尊重并保护所有使用阅读用户的个人隐私权,您注册的用户名、电子邮件地址等个人资料,非经您亲自许可或根据相关法律、法规的强制性规定,阅读不会主动地泄露给第三方。
* 阅读致力于最大程度地减少网络文学阅读者在自行搜寻过程中的无意义的时间浪费,通过专业搜索展示不同网站中网络文学的最新章节。
阅读在为广大小说爱好者提供方便、快捷舒适的试读体验的同时,也使优秀网络文学得以迅速、更广泛的传播,从而达到了在一定程度促进网络文学充分繁荣发展之目的。
阅读鼓励广大小说爱好者通过阅读发现优秀网络小说及其提供商,并建议阅读正版图书。
任何单位或个人认为通过阅读搜索链接到的第三方网页内容可能涉嫌侵犯其信息网络传播权,应该及时向阅读提出书面权力通知,并提供身份证明、权属证明及详细侵权情况证明。
阅读在收到上述法律文件后,将会依法尽快断开相关链接内容。
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Chapter</title>
<link href="../Styles/fonts.css" type="text/css" rel="stylesheet"/>
<link href="../Styles/main.css" type="text/css" rel="stylesheet"/>
</head>
<body>
<!--<div class="logo">
<img alt="" class="logo" src="../Images/logo.png"/>
</div>-->
<br/>
<br/>
<h2 class="head">{title}</h2>
{content}
</body>
</html>
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cover</title>
<style type="text/css">
.pic {
margin: 50% 30% 0 30%;
padding: 2px 2px;
border: 1px solid #f5f5dc;
background-color: rgba(250,250,250, 0);
border-radius: 1px;
}
</style>
</head>
<body style="text-align: center;">
<div class="pic"><img src="../Images/cover.jpg" style="width: 100%; height: auto;"/></div>
<h1 style="margin-top: 5%; font-size: 110%;">{name}</h1>
<div class="author" style="margin-top: 0;"><b>{author}</b> <span style="font-size: smaller;">/ 著</span></div>
</body>
</html>
+267
View File
@@ -0,0 +1,267 @@
@charset "utf-8";
/*---常用---*/
@font-face {
font-family: "zw";
src:
local("宋体"),local("明体"),local("明朝"),
local("Songti"),local("Songti SC"),local("Songti TC"), /*iOS6+iBooks3*/
local("Song S"),local("Song T"),local("STBShusong"),local("TBMincho"),local("HYMyeongJo"), /*Kindle Paperwihite*/
local("DK-SONGTI"),
url(../Fonts/zw.ttf),
url(res:///opt/sony/ebook/FONT/zw.ttf),
url(res:///Data/FONT/zw.ttf),
url(res:///opt/sony/ebook/FONT/tt0011m_.ttf),
url(res:///ebook/fonts/../../mnt/sdcard/fonts/zw.ttf),
url(res:///ebook/fonts/../../mnt/extsd/fonts/zw.ttf),
url(res:///ebook/fonts/zw.ttf),
url(res:///ebook/fonts/DroidSansFallback.ttf),
url(res:///fonts/ttf/zw.ttf),
url(res:///../../media/mmcblk0p1/fonts/zw.ttf),
url(file:///mnt/us/DK_System/system/fonts/zw.ttf), /*Duokan Old Path*/
url(file:///mnt/us/DK_System/xKindle/res/userfonts/zw.ttf), /*Duokan 2012 Path*/
url(res:///abook/fonts/zw.ttf),
url(res:///system/fonts/zw.ttf),
url(res:///system/media/sdcard/fonts/zw.ttf),
url(res:///media/fonts/zw.ttf),
url(res:///sdcard/fonts/zw.ttf),
url(res:///system/fonts/DroidSansFallback.ttf),
url(res:///mnt/MOVIFAT/font/zw.ttf),
url(res:///media/flash/fonts/zw.ttf),
url(res:///media/sd/fonts/zw.ttf),
url(res:///opt/onyx/arm/lib/fonts/AdobeHeitiStd-Regular.otf),
url(res:///../../fonts/zw.ttf),
url(res:///../fonts/zw.ttf),
url(../../../../../zw.ttf), /*EpubReaderI*/
url(res:///mnt/sdcard/fonts/zw.ttf), /*Nook for Android: fonts in TF Card*/
url(res:///fonts/zw.ttf), /*ADE1,8, 2.0 Program Path*/
url(res:///../../../../Windows/fonts/zw.ttf);
/*ADE1,8, 2.0 Windows Path*/;
}
@font-face {
font-family: "fs";
src:
local("amasis30"),local("仿宋"),local("仿宋_GB2312"),
local("Yuanti"),local("Yuanti SC"),local("Yuanti TC"), /*iOS6+iBooks3*/
local("DK-FANGSONG"),
url(../Fonts/fs.ttf),
url(res:///opt/sony/ebook/FONT/fs.ttf),
url(res:///Data/FONT/fs.ttf),
url(res:///opt/sony/ebook/FONT/tt0011m_.ttf),
url(res:///ebook/fonts/../../mnt/sdcard/fonts/fs.ttf),
url(res:///ebook/fonts/../../mnt/extsd/fonts/fs.ttf),
url(res:///ebook/fonts/fs.ttf),
url(res:///ebook/fonts/DroidSansFallback.ttf),
url(res:///fonts/ttf/fs.ttf),
url(res:///../../media/mmcblk0p1/fonts/fs.ttf),
url(file:///mnt/us/DK_System/system/fonts/fs.ttf), /*Duokan Old Path*/
url(file:///mnt/us/DK_System/xKindle/res/userfonts/fs.ttf), /*Duokan 2012 Path*/
url(res:///abook/fonts/fs.ttf),
url(res:///system/fonts/fs.ttf),
url(res:///system/media/sdcard/fonts/fs.ttf),
url(res:///media/fonts/fs.ttf),
url(res:///sdcard/fonts/fs.ttf),
url(res:///system/fonts/DroidSansFallback.ttf),
url(res:///mnt/MOVIFAT/font/fs.ttf),
url(res:///media/flash/fonts/fs.ttf),
url(res:///media/sd/fonts/fs.ttf),
url(res:///opt/onyx/arm/lib/fonts/AdobeHeitiStd-Regular.otf),
url(res:///../../fonts/fs.ttf),
url(res:///../fonts/fs.ttf),
url(../../../../../fs.ttf), /*EpubReaderI*/
url(res:///mnt/sdcard/fonts/fs.ttf), /*Nook for Android: fonts in TF Card*/
url(res:///fonts/fs.ttf), /*ADE1,8, 2.0 Program Path*/
url(res:///../../../../Windows/fonts/fs.ttf);
/*ADE1,8, 2.0 Windows Path*/;
}
@font-face {
font-family: "kt";
src:
local("Caecilia"),local("楷体"),local("楷体_GB2312"),
local("Kaiti"),local("Kaiti SC"),local("Kaiti TC"), /*iOS6+iBooks3*/
local("MKai PRC"),local("MKaiGB18030C-Medium"),local("MKaiGB18030C-Bold"), /*Kindle Paperwihite*/
local("DK-KAITI"),
url(../Fonts/kt.ttf),
url(res:///opt/sony/ebook/FONT/kt.ttf),
url(res:///Data/FONT/kt.ttf),
url(res:///opt/sony/ebook/FONT/tt0011m_.ttf),
url(res:///ebook/fonts/../../mnt/sdcard/fonts/kt.ttf),
url(res:///ebook/fonts/../../mnt/extsd/fonts/kt.ttf),
url(res:///ebook/fonts/kt.ttf),
url(res:///ebook/fonts/DroidSansFallback.ttf),
url(res:///fonts/ttf/kt.ttf),
url(res:///../../media/mmcblk0p1/fonts/kt.ttf),
url(file:///mnt/us/DK_System/system/fonts/kt.ttf), /*Duokan Old Path*/
url(file:///mnt/us/DK_System/xKindle/res/userfonts/kt.ttf), /*Duokan 2012 Path*/
url(res:///abook/fonts/kt.ttf),
url(res:///system/fonts/kt.ttf),
url(res:///system/media/sdcard/fonts/kt.ttf),
url(res:///media/fonts/kt.ttf),
url(res:///sdcard/fonts/kt.ttf),
url(res:///system/fonts/DroidSansFallback.ttf),
url(res:///mnt/MOVIFAT/font/kt.ttf),
url(res:///media/flash/fonts/kt.ttf),
url(res:///media/sd/fonts/kt.ttf),
url(res:///opt/onyx/arm/lib/fonts/AdobeHeitiStd-Regular.otf),
url(res:///../../fonts/kt.ttf),
url(res:///../fonts/kt.ttf),
url(../../../../../kt.ttf), /*EpubReaderI*/
url(res:///mnt/sdcard/fonts/kt.ttf), /*Nook for Android: fonts in TF Card*/
url(res:///fonts/kt.ttf), /*ADE1,8, 2.0 Program Path*/
url(res:///../../../../Windows/fonts/kt.ttf);
/*ADE1,8, 2.0 Windows Path*/;
}
@font-face {
font-family: "ht";
src:
local("黑体"),local("微软雅黑"),
local("Heiti"),local("Heiti SC"),local("Heiti TC"), /*iOS6+iBooks3*/
local("MYing Hei S"),local("MYing Hei T"),local("TBGothic"), /*Kindle Paperwihite*/
local("DK-HEITI"),
url(../Fonts/ht.ttf),
url(res:///opt/sony/ebook/FONT/ht.ttf),
url(res:///Data/FONT/ht.ttf),
url(res:///opt/sony/ebook/FONT/tt0011m_.ttf),
url(res:///ebook/fonts/../../mnt/sdcard/fonts/ht.ttf),
url(res:///ebook/fonts/../../mnt/extsd/fonts/ht.ttf),
url(res:///ebook/fonts/ht.ttf),
url(res:///ebook/fonts/DroidSansFallback.ttf),
url(res:///fonts/ttf/ht.ttf),
url(res:///../../media/mmcblk0p1/fonts/ht.ttf),
url(file:///mnt/us/DK_System/system/fonts/ht.ttf), /*Duokan Old Path*/
url(file:///mnt/us/DK_System/xKindle/res/userfonts/ht.ttf), /*Duokan 2012 Path*/
url(res:///abook/fonts/ht.ttf),
url(res:///system/fonts/ht.ttf),
url(res:///system/media/sdcard/fonts/ht.ttf),
url(res:///media/fonts/ht.ttf),
url(res:///sdcard/fonts/ht.ttf),
url(res:///system/fonts/DroidSansFallback.ttf),
url(res:///mnt/MOVIFAT/font/ht.ttf),
url(res:///media/flash/fonts/ht.ttf),
url(res:///media/sd/fonts/ht.ttf),
url(res:///opt/onyx/arm/lib/fonts/AdobeHeitiStd-Regular.otf),
url(res:///../../fonts/ht.ttf),
url(res:///../fonts/ht.ttf),
url(../../../../../ht.ttf), /*EpubReaderI*/
url(res:///mnt/sdcard/fonts/ht.ttf), /*Nook for Android: fonts in TF Card*/
url(res:///fonts/ht.ttf), /*ADE1,8, 2.0 Program Path*/
url(res:///../../../../Windows/fonts/ht.ttf);
/*ADE1,8, 2.0 Windows Path*/;
}
@font-face {
font-family:"h1";
src:
local("方正兰亭特黑长_GBK"),local("方正兰亭特黑长简体"),local("方正兰亭特黑长繁体"),
local("LantingTeheichang"),
local("Yuanti"),local("Yuanti SC"),local("Yuanti TC"),
local("DK-HEITI"),
url(../Fonts/h1.ttf),
url(res:///opt/sony/ebook/FONT/h1.ttf),
url(res:///Data/FONT/h1.ttf),
url(res:///opt/sony/ebook/FONT/tt0011m_.ttf),
url(res:///ebook/fonts/../../mnt/sdcard/fonts/h1.ttf),
url(res:///ebook/fonts/../../mnt/extsd/fonts/h1.ttf),
url(res:///ebook/fonts/h1.ttf),
url(res:///ebook/fonts/DroidSansFallback.ttf),
url(res:///fonts/ttf/h1.ttf),
url(res:///../../media/mmcblk0p1/fonts/h1.ttf),
url(file:///mnt/us/DK_System/system/fonts/h1.ttf), /*Duokan Old Path*/
url(file:///mnt/us/DK_System/xKindle/res/userfonts/h1.ttf), /*Duokan 2012 Path*/
url(res:///abook/fonts/h1.ttf),
url(res:///system/fonts/h1.ttf),
url(res:///system/media/sdcard/fonts/h1.ttf),
url(res:///media/fonts/h1.ttf),
url(res:///sdcard/fonts/h1.ttf),
url(res:///system/fonts/DroidSansFallback.ttf),
url(res:///mnt/MOVIFAT/font/h1.ttf),
url(res:///media/flash/fonts/h1.ttf),
url(res:///media/sd/fonts/h1.ttf),
url(res:///opt/onyx/arm/lib/fonts/AdobeHeitiStd-Regular.otf),
url(res:///../../fonts/h1.ttf),
url(res:///../fonts/h1.ttf),
url(../../../../../h1.ttf), /*EpubReaderI*/
url(res:///mnt/sdcard/fonts/h1.ttf), /*Nook for Android: fonts in TF Card*/
url(res:///fonts/h1.ttf), /*ADE1,8, 2.0 Program Path*/
url(res:///../../../../Windows/fonts/h1.ttf); /*ADE1,8, 2.0 Windows Path*/
}
@font-face {
font-family:"h2";
src:
local("方正大标宋_GBK"),local("方正大标宋简体"),local("方正大标宋繁体"),
local("Dabiaosong"),
local("Heiti"),local("Heiti SC"),local("Heiti TC"),
local("DK-XIAOBIAOSONG"),
url(../Fonts/h2.ttf),
url(res:///opt/sony/ebook/FONT/h2.ttf),
url(res:///Data/FONT/h2.ttf),
url(res:///opt/sony/ebook/FONT/tt0011m_.ttf),
url(res:///ebook/fonts/../../mnt/sdcard/fonts/h2.ttf),
url(res:///ebook/fonts/../../mnt/extsd/fonts/h2.ttf),
url(res:///ebook/fonts/h2.ttf),
url(res:///ebook/fonts/DroidSansFallback.ttf),
url(res:///fonts/ttf/h2.ttf),
url(res:///../../media/mmcblk0p1/fonts/h2.ttf),
url(file:///mnt/us/DK_System/system/fonts/h2.ttf), /*Duokan Old Path*/
url(file:///mnt/us/DK_System/xKindle/res/userfonts/h2.ttf), /*Duokan 2012 Path*/
url(res:///abook/fonts/h2.ttf),
url(res:///system/fonts/h2.ttf),
url(res:///system/media/sdcard/fonts/h2.ttf),
url(res:///media/fonts/h2.ttf),
url(res:///sdcard/fonts/h2.ttf),
url(res:///system/fonts/DroidSansFallback.ttf),
url(res:///mnt/MOVIFAT/font/h2.ttf),
url(res:///media/flash/fonts/h2.ttf),
url(res:///media/sd/fonts/h2.ttf),
url(res:///opt/onyx/arm/lib/fonts/AdobeHeitiStd-Regular.otf),
url(res:///../../fonts/h2.ttf),
url(res:///../fonts/h2.ttf),
url(../../../../../h2.ttf), /*EpubReaderI*/
url(res:///mnt/sdcard/fonts/h2.ttf), /*Nook for Android: fonts in TF Card*/
url(res:///fonts/h2.ttf), /*ADE1,8, 2.0 Program Path*/
url(res:///../../../../Windows/fonts/h2.ttf); /*ADE1,8, 2.0 Windows Path*/
}
@font-face {
font-family:"h3";
src:
local("方正华隶_GBK"),local("方正行黑简体"),local("方正行黑繁体"),
local("Yuanti"),local("Yuanti SC"),local("Yuanti TC"),
local("DK-FANGSONG"),
url(../Fonts/h3.ttf),
url(res:///opt/sony/ebook/FONT/h3.ttf),
url(res:///Data/FONT/h3.ttf),
url(res:///opt/sony/ebook/FONT/tt0011m_.ttf),
url(res:///ebook/fonts/../../mnt/sdcard/fonts/h3.ttf),
url(res:///ebook/fonts/../../mnt/extsd/fonts/h3.ttf),
url(res:///ebook/fonts/h3.ttf),
url(res:///ebook/fonts/DroidSansFallback.ttf),
url(res:///fonts/ttf/h3.ttf),
url(res:///../../media/mmcblk0p1/fonts/h3.ttf),
url(file:///mnt/us/DK_System/system/fonts/h3.ttf), /*Duokan Old Path*/
url(file:///mnt/us/DK_System/xKindle/res/userfonts/h3.ttf), /*Duokan 2012 Path*/
url(res:///abook/fonts/h3.ttf),
url(res:///system/fonts/h3.ttf),
url(res:///system/media/sdcard/fonts/h3.ttf),
url(res:///media/fonts/h3.ttf),
url(res:///sdcard/fonts/h3.ttf),
url(res:///system/fonts/DroidSansFallback.ttf),
url(res:///mnt/MOVIFAT/font/h3.ttf),
url(res:///media/flash/fonts/h3.ttf),
url(res:///media/sd/fonts/h3.ttf),
url(res:///opt/onyx/arm/lib/fonts/AdobeHeitiStd-Regular.otf),
url(res:///../../fonts/h3.ttf),
url(res:///../fonts/h3.ttf),
url(../../../../../h3.ttf), /*EpubReaderI*/
url(res:///mnt/sdcard/fonts/h3.ttf), /*Nook for Android: fonts in TF Card*/
url(res:///fonts/h3.ttf), /*ADE1,8, 2.0 Program Path*/
url(res:///../../../../Windows/fonts/h3.ttf); /*ADE1,8, 2.0 Windows Path*/
}
@font-face {
font-family:"luohua";
src:local("汉仪落花体"),
url("../Fonts/hylh.ttf");
}
+11
View File
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN">
<head>
<title>Intro</title>
<link href="../Styles/fonts.css" type="text/css" rel="stylesheet" />
<link href="../Styles/main.css" type="text/css" rel="stylesheet" />
</head>
<body>
<h1 class="head" style="margin-bottom:2em;">内容简介</h1>{intro}</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

+551
View File
@@ -0,0 +1,551 @@
@charset "utf-8";
@import url("../Styles/fonts.css");
body {
padding: 0%;
margin-top: 0%;
margin-bottom: 0%;
margin-left: 0.5%;
margin-right: 0.5%;
line-height: 130%;
text-align: justify;
font-family: "DK-SONGTI","st","宋体","zw",sans-serif;
}
p {
text-align: justify;
text-indent: 2em;
line-height: 130%;
margin-right: 0.5%;
margin-left: 0.5%;
font-family: "DK-SONGTI","st","宋体","zw",sans-serif;
}
p.kaiti {
font-family: "DK-KAITI","kt","楷体","zw",serif;
}
p.fangsong {
font-family: "DK-FANGSONG","fs","仿宋","zw",serif;
}
span.xinli {
font-family: "DK-KAITI","kt","楷体","zw",serif;
color: #4e753f;
}
/** 英文斜体字 **/
span.english{
font-style: italic;
}
div {
margin: 0px;
padding: 0px;
line-height: 120%;
text-align: justify;
font-family: "zw";
}
div.foot {
text-indent: 2em;
margin: 30% 5% 0 5%;
padding: 8px 0;
}
p.foot {
font-family: "DK-KAITI","kt","楷体","zw",serif;
}
/*扉页*/
.booksubtitle {
padding: 10px 0 0px 0;
text-indent: 0em;
font-size: 75%;
font-family: "ht";
}
.booktitle {
padding: 9% 0 0 0;
font-size: 1.3em;
font-family: "方正小标宋_GBK","DK-XIAOBIAOSONG";
font-weight: normal;
text-indent: 0em;
color: #000;
text-align: center;
line-height: 1.6;
}
.booktitle0 {
font-size: 1.2em;
font-family: "fs";
text-indent: 0em;
text-align: center;
line-height: 1.8;
}
.booktitle1 {
padding: 0 0 0 0;
font-size: 0.85em;
font-family: "fs";
text-indent: 0em;
text-align: center;
line-height: 1.6;
}
.bookauthor {
font-family: "DK-FANGSONG",仿,"fs","fangsong",sans-serif;
padding: 5% 5px 0px 5px;
text-indent: 0em;
text-align: center;
color: #000;
font-size: 90%;
line-height: 1.3;
}
.booktranslator {
padding: 1% 5px 0px 5px;
text-indent: 0em;
text-align: center;
font-size: 85%;
line-height: 1.3;
}
.bookpub {
font-family: "DK-KAITI","kt","楷体","楷体_gb2312";
padding: 30% 5px 5px 5px;
text-indent: 0em;
color: #000;
text-align: center;
font-size: 80%;
}
/*标题页*/
body.head {
background-repeat:no-repeat no-repeat;
background-size:160px 229px;
background-position:bottom right;
background-attachment:fixed;
}
body.xhead {
background-color: #FDF5E6;
}
h1.head {
font-family: "DK-HEITI",,sans-serif;
font-size: 1.2em;
font-weight: bold;
color: #311a02;
text-indent: 0em;
font-weight: normal;
duokan-text-indent: 0em;
padding: auto;
text-align: center;
margin-top: -8em;
}
div.head {
border: solid 2px #ffffff;
padding: 2px;
margin: 2em auto 0.7em auto;
text-align: center;
width: 1em;
}
h1.head b {
font-family: "方正小标宋_GBK","DK-XIAOBIAOSONG";
font-weight: bold;
font-size: 1.2em;
text-align: center;
text-indent: 0em;
duokan-text-indent: 0em;
color: #311a02;
margin: 0.5em auto;
line-height: 140%;
}
div.back {
text-align: center;
text-indent: 0em;
duokan-text-indent: 0em;
margin: 4em auto;
}
img.back {
width: 70%;
}
img.back2 {
width: 40%;
margin: 2em 0 0 0;
}
/*正文*/
/**楷体引文**/
.titou {
font-family: "DK-FANGSONG",仿,"fs","fangsong",sans-serif;
}
.yinwen {
font-family: "DK-KAITI","kt","楷体","zw",serif;
margin-left: 2em;
text-indent: 0em;
}
.nicename {
font-family: "DK-HEITI",,sans-serif;
font-weight: bold;
font-size: 0.9em;
}
body.head3 {
background-color: #a7bdcc;
color: #354f66;
}
body.head4 {
background-color: #bfd19b;
color: #4e753f;
}
h2.head {
font-family: "小标宋";
text-align: left;
font-weight: bold;
font-size: 1.1em;
margin: -3em 2em 2em 0;
color: #3f83e8;
line-height: 140%;
}
h2.head span {
font-family: "仿宋";
font-size: 0.7em;
background-color: #3f83e8;
border-radius: 9px;
padding: 4px;
color: #fff;
}
div.logo {
margin: -2em 0% 0 0;
text-align: right;
}
img.logo {
width: 40%;
}
.imgl {
/*图片居右*/
margin: -8.8em 1em 4em 0em;
width: 80%;
text-align: right;
}
h1.head {
line-height:130%;
font-size:1.4em;
text-align: center;
color: #BA2213;
font-weight: bold;
margin-top: 2em;
margin-bottom: 1em;
font-family: "方正小标宋_GBK","DK-XIAOBIAOSONG";
}
h3 {
font-family: "DK-HEITI",,sans-serif;
font-size: 1.1em;
margin: 1em 0;
border-left: 1.2em solid #00a1e9;
line-height: 120%;
padding-left: 3px;
color: #00a1e9;
}
h4 {
font-family: "DK-HEITI",,sans-serif;
font-size: 1.1em;
text-align: center;
margin: 1em 0;
line-height: 120%;
color: #000;
}
h1.post {
font-family: "方正小标宋_GBK","DK-XIAOBIAOSONG";
text-align: center;
font-size: 1.3em;
color: #026fca;
margin: 3em auto 2em auto;
}
.banquan {
font-family: "DK-FANGSONG",仿,"fs","fangsong",sans-serif;
text-align: left;
color: #000;
font-size:1.1em;
margin-bottom:1em;
text-indent: 1em;
duokan-text-indent: 1em;
}
p.post {
font-family: "DK-FANGSONG",仿,"fs","fangsong",sans-serif;
}
p.zy {
font-family: "DK-FANGSONG",仿,"fs","fangsong",sans-serif;
margin: 1em 0 0 1em;
padding: 5px 0px 5px 10px;
text-indent: 0em;
border-left: 5px solid #a9b5c1;
}
.sign {
font-family: "DK-KAITI","kt","楷体","zw",serif;
margin: 1em 2px 0 auto;
text-align: right;
font-size: 0.8em;
text-indent: 0em;
duokan-text-indent: 0em;
}
.mark {
font-family: "DK-HEITI",,sans-serif;
font-size: 0.9em;
color: #fff;
text-indent: 0em;
duokan-text-indent: 0em;
background-color: maroon;
text-align: center;
padding: 0px;
margin: 2em 30%;
}
/*出版社*/
.chubanshe img{
width:106px;
height:28px;
}
.chubanshe {
margin-top:20px;
}
.cr {
font-size:0.9em;
}
/*多看画廊*/
div.duokan-image-single {
text-align: center;
margin: 0.5em auto; /*插图盒子上下外边距为0.5em,左右设置auto是为了水平居中这个盒子*/
}
img.picture-80 {
margin: 0; /*清除img元素的外边距*/
width: 80%; /*预览窗口的宽度*/
box-shadow: 3px 3px 10px #bfbfbf; /*给图片添加阴影效果*/
}
p.duokan-image-maintitle {
margin: 1em 0 0; /*图片说明的段间距*/
font-family: "楷体"; /*图片说明使用的字体*/
font-size: 0.9em; /*字体大小*/
text-indent: 0; /*首行缩进为零,当你使用单标签p来指定首行缩进为2em时,记得在需要居中的文本中清除缩进,因为样式是叠加的*/
text-align: center; /*图片说明水平居中*/
color: #a52a2a; /*字体颜色*/
line-height: 1.25em; /*行高,防止有很长的图片说明*/
}
/*制作说明页*/
body.description {
background-image: url(../Images/001.png);
background-position: bottom center;
background-repeat: no-repeat;
background-size: cover;
padding: 25% 10% 0;
font-size: 0.9em;
}
div.description-body {
width: 55%;
padding: 2em 1.3em;
border-radius: 0.5em;
font-size: 0.9em;
border-style: solid;
border-color: #393939;
border-width: 0.3em;
border-radius: 5em;
background-color: #5a5a5a;
box-shadow: 2px 2px 3px #828281;
}
h1.description-title {
text-align: center;
font-family: "黑体";
font-size: 1.2em;
margin: 0 0 1em 0;
color: #FF9;
text-shadow: 1px 1px 0 black;
}
p.description-text {
color: #f9ddd2;
font-family: "准圆";
margin: 0;
text-align: justify;
text-indent: 0;
duokan-text-indent: 0;
}
hr.description-hr {
margin: 0.5em -1em;
border-style: dotted;
border-color: #9C9;
border-width: 0.05em 0 0 0;
}
p.tips {
text-align: justify;
text-indent: 0;
duokan-text-indent: 0;
font-family: "楷体";
font-size: 0.7em;
color: #FFC;
margin: 0;
}
/*版本说明页*/
.ver {
font-family: "DK-CODE","DK-XIHEITI",,"xihei",sans-serif;
font-weight: bold;
font-size: 100%;
color: #000;
margin: 1em 0 1em 0;
text-align: center;
}
.vertitle {
font-family: "DK-FANGSONG",仿,"fs","fangsong",sans-serif;
font-size: 100%;
text-indent: 0em;
text-align: left;
duokan-text-indent: 0em;
}
.vertxt {
font-family: "DK-FANGSONG",仿,"fs","fangsong",sans-serif;
line-height: 100%;
font-size: 85%;
text-indent: 0em;
text-align: left;
duokan-text-indent: 0em;
}
.verchar {
font-family: "DK-KAITI","kt","楷体","楷体_gb2312";
text-align: left;
text-indent: 1em;
duokan-text-indent: 1em;
margin-bottom: 1em;
margin-top: 1em;
}
.vernote {
font-family: "DK-FANGSONG",仿,"fs","fangsong",sans-serif;
font-size: 75%;
color: #686d70;
text-indent: 0em;
text-align: left;
duokan-text-indent: 0em;
padding-bottom: 15px;
}
.line {
border: dotted #A2906A;
border-width: 1px 0 0 0;
}
.entry {
margin-left: 18px;
font-size: 83%;
color: #8fe0a3;
text-indent: 0em;
duokan-text-indent: 0em;
}
/*版权信息*/
.vol {
text-indent: 0em;
text-align: center;
padding: 0.8em;
margin: 0 auto 3px auto;
color: #000;
font-family: "方正小标宋_GBK","DK-XIAOBIAOSONG";
font-size: 130%;
text-shadow: none;
}
.cp {
font-family: "DK-CODE","DK-XIHEITI",,"xihei",sans-serif;
color: #412938;
font-size: 70%;
text-align: left;
text-indent: 0em;
duokan-text-indent: 0em;
}
.xchar {
font-family: "DK-KAITI","kt","楷体","楷体_gb2312";
text-indent: 0em;
duokan-text-indent: 0em;
}
/*多看弹注*/
sup img {
line-height: 100%;
width: auto;
height: 1.0em;
margin: 0em;
padding: 0em;
vertical-align: text-top;
}
ol {
margin-bottom:0;
padding:0 auto;
list-style-type: decimal;
}
.hr {
width:50%;
margin:2em 0 0 0.5em;
padding:0;
height:2px;
background-color: #F3221D;
}
.duokan-footnote-content{
padding:0 auto;
text-align: left;
}
.duokan-footnote-item {
font-family:"DK-XIHEITI",,"xihei",sans-serif;
text-align: left;
font-size: 80%;
line-height: 100%;
clear: both;
color:#000;
list-style-type:decimal;
}
li.duokan-footnote-item a {
font-family:"DK-HEITI";
text-align: left;
}
a{
text-decoration: none;
color: #222;
}
a:hover {background: #81caf9}
a:active {background: yellow}
.duokan-image-maintitle {
font-family:"DK-HEITI",,"hei",sans-serif;
text-align: center;
text-indent: 0em;
duokan-text-indent: 0em;
font-size:90%;
color: #1F4150;
margin-top: 1em;
}
.duokan-image-subtitle {
font-family:"DK-XIHEITI",,"xihei",sans-serif;
text-align: center;
text-indent: 0em;
duokan-text-indent: 0em;
font-size:70%;
color: #3A3348;
margin-top: 1em;
}
Binary file not shown.
@@ -0,0 +1,156 @@
```java
public enum MimeTypeEnum {
AAC("acc", "AAC音频", "audio/aac"),
ABW("abw", "AbiWord文件", "application/x-abiword"),
ARC("arc", "存档文件", "application/x-freearc"),
AVI("avi", "音频视频交错格式", "video/x-msvideo"),
AZW("azw", "亚马逊Kindle电子书格式", "application/vnd.amazon.ebook"),
BIN("bin", "任何类型的二进制数据", "application/octet-stream"),
BMP("bmp", "Windows OS / 2位图图形", "image/bmp"),
BZ("bz", "BZip存档", "application/x-bzip"),
BZ2("bz2", "BZip2存档", "application/x-bzip2"),
CSH("csh", "C-Shell脚本", "application/x-csh"),
CSS("css", "级联样式表(CSS", "text/css"),
CSV("csv", "逗号分隔值(CSV", "text/csv"),
DOC("doc", "微软Word文件", "application/msword"),
DOCX("docx", "Microsoft WordOpenXML", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
EOT("eot", "MS Embedded OpenType字体", "application/vnd.ms-fontobject"),
EPUB("epub", "电子出版物(EPUB", "application/epub+zip"),
GZ("gz", "GZip压缩档案", "application/gzip"),
GIF("gif", "图形交换格式(GIF", "image/gif"),
HTM("htm", "超文本标记语言(HTML", "text/html"),
HTML("html", "超文本标记语言(HTML", "text/html"),
ICO("ico", "图标格式", "image/vnd.microsoft.icon"),
ICS("ics", "iCalendar格式", "text/calendar"),
JAR("jar", "Java存档", "application/java-archive"),
JPEG("jpeg", "JPEG图像", "image/jpeg"),
JPG("jpg", "JPEG图像", "image/jpeg"),
JS("js", "JavaScript", "text/javascript"),
JSON("json", "JSON格式", "application/json"),
JSONLD("jsonld", "JSON-LD格式", "application/ld+json"),
MID("mid", "乐器数字接口(MIDI", "audio/midi"),
MIDI("midi", "乐器数字接口(MIDI", "audio/midi"),
MJS("mjs", "JavaScript模块", "text/javascript"),
MP3("mp3", "MP3音频", "audio/mpeg"),
MPEG("mpeg", "MPEG视频", "video/mpeg"),
MPKG("mpkg", "苹果安装程序包", "application/vnd.apple.installer+xml"),
ODP("odp", "OpenDocument演示文稿文档", "application/vnd.oasis.opendocument.presentation"),
ODS("ods", "OpenDocument电子表格文档", "application/vnd.oasis.opendocument.spreadsheet"),
ODT("odt", "OpenDocument文字文件", "application/vnd.oasis.opendocument.text"),
OGA("oga", "OGG音讯", "audio/ogg"),
OGV("ogv", "OGG视频", "video/ogg"),
OGX("ogx", "OGG", "application/ogg"),
OPUS("opus", "OPUS音频", "audio/opus"),
OTF("otf", "otf字体", "font/otf"),
PNG("png", "便携式网络图形", "image/png"),
PDF("pdf", "Adobe 可移植文档格式(PDF", "application/pdf"),
PHP("php", "php", "application/x-httpd-php"),
PPT("ppt", "Microsoft PowerPoint", "application/vnd.ms-powerpoint"),
PPTX("pptx", "Microsoft PowerPointOpenXML", "application/vnd.openxmlformats-officedocument.presentationml.presentation"),
RAR("rar", "RAR档案", "application/vnd.rar"),
RTF("rtf", "富文本格式", "application/rtf"),
SH("sh", "Bourne Shell脚本", "application/x-sh"),
SVG("svg", "可缩放矢量图形(SVG", "image/svg+xml"),
SWF("swf", "小型Web格式(SWF)或Adobe Flash文档", "application/x-shockwave-flash"),
TAR("tar", "磁带存档(TAR", "application/x-tar"),
TIF("tif", "标记图像文件格式(TIFF", "image/tiff"),
TIFF("tiff", "标记图像文件格式(TIFF", "image/tiff"),
TS("ts", "MPEG传输流", "video/mp2t"),
TTF("ttf", "ttf字体", "font/ttf"),
TXT("txt", "文本(通常为ASCII或ISO 8859- n", "text/plain"),
VSD("vsd", "微软Visio", "application/vnd.visio"),
WAV("wav", "波形音频格式", "audio/wav"),
WEBA("weba", "WEBM音频", "audio/webm"),
WEBM("webm", "WEBM视频", "video/webm"),
WEBP("webp", "WEBP图像", "image/webp"),
WOFF("woff", "Web开放字体格式(WOFF", "font/woff"),
WOFF2("woff2", "Web开放字体格式(WOFF", "font/woff2"),
XHTML("xhtml", "XHTML", "application/xhtml+xml"),
XLS("xls", "微软Excel", "application/vnd.ms-excel"),
XLSX("xlsx", "微软ExcelOpenXML", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
XML("xml", "XML", "application/xml"),
XUL("xul", "XUL", "application/vnd.mozilla.xul+xml"),
ZIP("zip", "ZIP", "application/zip"),
MIME_3GP("3gp", "3GPP audio/video container", "video/3gpp"),
MIME_3GP_WITHOUT_VIDEO("3gp", "3GPP audio/video container doesn't contain video", "audio/3gpp2"),
MIME_3G2("3g2", "3GPP2 audio/video container", "video/3gpp2"),
MIME_3G2_WITHOUT_VIDEO("3g2", "3GPP2 audio/video container doesn't contain video", "audio/3gpp2"),
MIME_7Z("7z", "7-zip存档", "application/x-7z-compressed")
}
```
@@ -0,0 +1,25 @@
# 书源管理界面帮助
* 书源右上角标志
* 绿点表示书源有发现,且启用了发现
* 红点表示书源有发现,但是未启用
* 没有标志表示此书源没有发现
* 右上角有分组菜单,可以按分组筛选书源
* 右上角更多菜单里包含
* 新建书源
* 本地导入
* 网络导入
* 二维码导入
* 分享选中源
* 选择源的更多操作在右下角的菜单里面,操作都是针对选择的书源
* 启用所选
* 禁用所选
* 添加分组
* 移除分组
* 启用发现
* 禁用发现
* 置顶所选
* 置底所选
* 导出所选
* 校验所选
* 校验失败的书源分组会加上"失效",选择"失效"分组即可批量操作
@@ -0,0 +1,21 @@
# 订阅源管理界面帮助
* 订阅源可以通过规则订阅一些网络内容
* 书源右上角标志
* 绿点表示书源有发现,且启用了发现
* 红点表示书源有发现,但是未启用
* 没有标志表示此书源没有发现
* 右上角有分组菜单,可以按分组筛选书源
* 右上角更多菜单里包含
* 新建订阅源
* 本地导入
* 网络导入
* 二维码导入
* 分享选中源
* 选择源的更多操作在右下角的菜单里面,操作都是针对选择的书源
* 启用所选
* 禁用所选
* 置顶所选
* 置底所选
* 导出所选
* 校验失败的书源分组会加上"失效",选择"失效"分组即可批量操作
+190
View File
@@ -0,0 +1,190 @@
# 帮助文档
## **新人必读**
【温馨提醒】 *本帮助可以在我的-右上角帮助按钮再次打开,更新前一定要做好备份,以免数据丢失!*
1. 为什么第一次安装好之后什么东西都没有?
* 阅读只是一个转码工具,不提供内容,第一次安装app,需要自己手动导入书源,可以从公众号 **[开源阅读]**、QQ群、酷安评论里获取由书友制作分享的书源。
2. 正文出现缺字漏字、内容缺失、排版错乱等情况,如何处理?
* 有可能是净化规则出现问题,先关闭替换净化并刷新,再观察是否正常。如果正常说明净化规则存在误杀,如果关闭后仍然出现相关问题,请点击源链接查看原文与正文是否相同,如果不同,再进行反馈。
3. 漫画源看书显示乱码,如何解决?
* 异次元和阅读是两个不同的软件,**两个软件的源并不通用**,请导入阅读的支持的漫画源!
## 书源相关
1. 如何导入本地书源文件?
* 下载群文件里的书源文件(书源格式后缀有txt、json,其中json文件某些情况下无法导入,需要修改后缀为txt格式才可导入);
* 打开阅读软件;
* 我的 - 点击“书源管理”;
* 点击右上角选择“本地导入”;
* 左下角选择书源文件所在的路径;
* 点击书源文件导入;
* 导入后返回书源管理界面;
* 新版qq下载路径:Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/
![QQ导入书源](https://cdn.jsdelivr.net/gh/gedoor/gedoor.github.io@master/images/importSource.jpg)
2. 如何新建大佬发的单独书源?
* 复制书源代码;
* 打开阅读软件;
* 我的 - 点击“书源管理”;
* 右上角选择“新建书源”;
* 进入新建书源后点击右上角“粘贴源”;
* 粘贴书源完成后点击上方保存;
* 本次新建单独书源操作完成。
* 注:如果书源有错误或者复制不全会显示格式错误,请重新复制。
3. 为什么导入2.0书源后无法阅读?
* 部分2.0书源并不适用于3.0版本的阅读,建议导入后进行筛选。
4. 阅读2.0数据如何导入阅读3.0
* 先对阅读2.0的数据进行备份,然后进入阅读3.0,点击“我的”,选择“备份与恢复”,再点击“导入旧版本数据”。
5. 如何给朋友分享我的书源?
* 打开阅读软件;
* 点击备份;
* 打开手机自带的文件管理;
* 手机自带内存根目录找到YueDu3.0文件夹;
* 找到myBookSource.json长按选择分享;
* 选择微信分享或者QQ分享;
* 选择你要分享的好友点击发送;
* 好友接收后在手机自带内存根目录找到myBookSource.json文件(最新版QQ 安卓10及以下版本在Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/,安卓11版本用户由于系统限制无法访问data目录,微信在Tencent/MicroMsg/Download);
* 复制该文件到手机自带内存根目录找到YueDu3.0文件夹(如已有该文件请先删除该文件或者备份到其他地方再复制到文件夹);
* 打开阅读软件点击恢复。
* 注:备份路径如已修改过请在修改后的路径下查找书源文件。
6. 效验书源显示失效就说明书源不能用了吗?
* 效验书源只是测试书源,可以做个参考,失效了不代表书源不能用了。
7. 发现和正版书源能不能使用?
* 发现和正版书源只能用来找书,看排行榜,不能用来看书,如需看书请切换书源。
8. 为什么书源这么多,发现里却只有一点点?
* 书源想要在发现界面里显示需要在书源里添加发现规则,并不是所有书源都有发现规则。
## 本地书籍相关
1. 目前阅读支持哪些格式的本地书籍?
* 目前支持TXT、EPUB格式
2. 如何导入本地书籍?
* 在书架页面点击右上角,选择“添加本地”,授予相关权限后即可导入本地书籍。也可在文件管理器中使用 **阅读** 打开相关书籍。
3. 导入TXT文件提示“LoadTocError”或“List is empty”是怎么回事?
* 请先去应用详情中确认是否授予了阅读“读写手机存储”的权限。
* 自动识别目录失败,可能是相关目录规则未开启,请点击右上角的换源按钮手动更换目录规则。
* 如果尝试所有规则均无法识别,请在github上提交issue并附件相关txt文件,也可以发送邮件至i@qnmlgb.trade(标题:legado本地文件章节无法识别,内容对其具体情况进行简要说明,附件上传相关txt文件)。
4. 如何下载书籍到本地?
* 把在线书籍加入到书架后,在书架页面点击右上角,选择“离线缓存”即可。
5. 如何自定义导出的txt/epub文件名称?
* 点击 **离线缓存** - **导出文件名**.
* 使用方法:
- 导出文件名支持js语法
- 可用变量: name - 书名 author-作者
- 示例:
> {name+"作者:"+author}
- 导出文件名:
> Legado是最好的在线阅读软件 作者: kunfei.
**注意:** name、author等变量与字符串的拼接都需要在js环境中进行,即必须使用{ } 将变量与字符串包裹起来.
6. 为什么我打开本地的TXT文件,显示内容却是乱码?
* 部分编码在阅读上会识别错误,建议先用文本编辑器转换为常用的UTF-8格式。
7. 阅读对部分把正文(如所有含引号的句子)识别成标题,如何解决?
* 点击右上角更换目录规则即可。
## 书籍界面相关
1. 如何刷新书架?
* 在书架界面下拉即可刷新。
2. 书架界面书籍右上角的红色或者灰色背景小数字代表什么?
* 红色代表书籍有更新,灰色代表无更新,数字代表未读章节。
3. 如何查看书籍详情?
* 长按书籍。
4. 如何对书架上的书进行删除、切换书架的操作?
* 书籍详情页操作即可。
5. 如何禁止或允许某本书更新?
* 书籍详情页,点击右上角 - “允许更新”。
6. 如何更换小说封面、名字、作者或简介?
* 书籍详情页,点击右上角修改按钮。
7. 怎么使用自定义字体?
* 阅读界面 - 字体-点击右上角选择字体文件路径。
8. 目前支持哪些格式的字体文件?
* 目前支持ttf、otf格式。
9. 书籍经常“正在加载中”怎么办?
* 在线书籍出现这个问题通常是由于源质量不好或不兼容引起的,可以换其它源多试试;本地书籍出现这个问题大概率是目录规则问题,手动切换规则可以解决。
10. 书籍内容只有标题,正文内容是路径怎么办?
* 通常是缓存路径引起的,更换缓存路径即可。
11. 看书时如遇到“目录为空”、“加载失败”和长串英文等情况怎么办?
* 在线书籍一般是书源问题,切换或更新书源即可。本地书籍请尝试手动更换目录规则。
12. 为什么每一章的最后一页,阅读的文字和横线背景总是对不齐?
* 请在 设置-文字底部对齐 选项中关闭底部对齐,再调整排版。
13. 漫画源或图片章节只能看到第一页,如何解决?
* 请先查看原网页是否正常,若正常,请在书籍阅读界面点击右上角的 **⁝** 按钮,在弹出的菜单中,选择 **翻页动画(本书)**,将翻页动画更改为 **滚动**
14. 阅读图片章节、漫画或epub插图时,图片被缩放到一页中,以至无法看清,如何处理?
* 临时处理方案:长按图片可以进行双指缩放。图片章节请先参考Q13中的方案将翻页动画更改为**滚动**
* 3.0旧版可以点击书籍界面的章节标题进入 **编辑书源** 界面,在 正文-图片样式 中填入 *full*,保存更改,刷新当前章节即可。
* 3.0新版可以直接在书籍阅读界面点击右上角的 **⁝** 按钮,选择 图片样式- *full*.
## 替换净化相关
1. 替换净化是什么?
* 替换净化可以去除书籍内容里的广告、错别字、屏蔽词等。
2. 如何自己填写净化替换规则?
* 第一行:替换规则名称 - 根据自己需求对替换净化规则进行命名;
* 第二行:分组 - 净化规则的分组组别;
* 第三行:替换规则 - 填写需要被替换的内容;
* 第四行:替换为 - 填写想替换成的内容(如不填则默认表示删除第三行里填写的内容);
* 第五行:替换范围,选填书名或者源名 - 填写此替换净化规则需要对哪本书籍或者哪个书源生效(如不填则对所有书籍和书源生效)。
* 注:如常规去除方法去除不掉,则需要勾选“使用正则表达式”,同时第三行里的替换规则也需要按照正则表达式来填写(正则表达式填写方法可自行百度学习)。
## 备份相关
1. 云备份在哪?
* 我的 - 备份与恢复 - WebDav设置。
2. 如何操作进行云备份?
* 侧栏设置,WebDav设置;
* 正确填写WebDAV 服务器地址、WebDAV 账号、WebDAV 密码;(要获得这三项的信息,需要注册一个坚果云账号,如果直接在手机上注册,坚果云会让你下载app,过程比较麻烦,为了一步到位,最好是在电脑上打开这个注册链接:https://www.jianguoyun.com/d/signup ;注册后,进入坚果云;点击右上角账户名处选择 “账户信息”,然后选择“安全选项”;在“安全选项” 中找到“第三方应用管理”,并选择“添加应用”,输入名称如“阅读”后,会生成密码,选择完成;其中 https://dav.jianguoyun.com/dav/ 就是填入“WebDAV 服务器地址”的内容,“使用情况”后面的邮箱地址就是你的“WebDAV 账号”,点击显示密码后得到的密码就是你的“WebDAV 密码”。)
* 无需操作,APP默认每天自动云备份一次。
3. 关于云备份的相关说明
* 在正确设置好云备份的情况下,APP默认每天自动云备份一次,当日多次手动云备份会对当日的旧云备份文件进行覆盖,并不会覆盖之前及之后不同日期的备份文件,每天所自动云备份的文件会按照日期进行命名。
4. 本地备份和云备份都能备份哪些东西?
* 书架、看书进度、搜索记录、书源、替换、APP设置等都会备份,基本涵盖所有内容。
5. 出现某些未知bug怎么办?
* 清除软件数据试试看,不行再进行反馈。
## 其他
1. 如何听书?
* 可以使用手机自带的朗读引擎,也可使用第三方如谷歌、小米等朗读引擎。
* 【具体操作:安装-系统设置-其他高级设置-辅助功能-TTS输出-选择安装的朗读引擎(不同品牌手机的操作方法及步骤也不同,视情况而定)。】
2. 如何设置屏幕方向、屏幕显示时长、显示/隐藏状态栏、显示/隐藏导航栏、音量键翻页、长按选择文本、点击总是翻下一页、自定义翻页案件?
* 阅读界面,设置(可上划,下面还有其他设置)。
3. 搜索的时候感觉手机卡顿,如何解决?
* 我的 - 其他设置 - “更新和搜索线程数”调低。
+22
View File
@@ -0,0 +1,22 @@
# 书源调试
* 调试搜索>>输入关键字,如:
```
系统
```
* 调试发现>>输入发现URL,如:
```
月票榜::https://www.qidian.com/rank/yuepiao?page={{page}}
```
* 调试详情页>>输入详情页URL,如:
```
https://m.qidian.com/book/1015609210
```
* 调试目录页>>输入目录页URL,如:
```
++https://www.zhaishuyuan.com/read/30394
```
* 调试正文页>>输入正文页URL,如:
```
--https://www.zhaishuyuan.com/chapter/30394/20940996
```
+15
View File
@@ -0,0 +1,15 @@
# 在线朗读规则说明
* 在线朗读规则为url规则,同书源url
* js参数
```
speakText //朗读文本
speakSpeed //朗读速度,0-45
```
* 例:
```
http://tts.baidu.com/text2audio,{
"method": "POST",
"body": "tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio"
}
```
File diff suppressed because one or more lines are too long
+204
View File
@@ -0,0 +1,204 @@
# 正则表达式学习
- [基本匹配]
- [元字符]
- [英文句号]
- [字符集]
- [否定字符集]
- [重复]
- [星号]
- [加号]
- [问号]
- [花括号]
- [字符组]
- [分支结构]
- [转义特殊字符]
- [定位符]
- [插入符号]
- [美元符号]
- [简写字符集]
- [断言]
- [正向先行断言]
- [负向先行断言]
- [正向后行断言]
- [负向后行断言]
- [标记]
- [不区分大小写]
- [全局搜索]
- [多行匹配]
- [常用正则表达式]
## 1. 基本匹配
正则表达式只是我们用于在文本中检索字母和数字的模式。例如正则表达式 `cat`,表示: 字母 `c` 后面跟着一个字母 `a`,再后面跟着一个字母 `t`。<pre>"cat" => The <a href="#learn-regex"><strong>cat</strong></a> sat on the mat</pre>
正则表达式 `123` 会匹配字符串 "123"。通过将正则表达式中的每个字符逐个与要匹配的字符串中的每个字符进行比较,来完成正则匹配。
正则表达式通常区分大小写,因此正则表达式 `Cat` 与字符串 "cat" 不匹配。<pre>"Cat" => The cat sat on the <a href="#learn-regex"><strong>Cat</strong></a></pre>
## 2. 元字符
元字符是正则表达式的基本组成元素。元字符在这里跟它通常表达的意思不一样,而是以某种特殊的含义去解释。有些元字符写在方括号内的时候有特殊含义。
元字符如下:
|元字符|描述|
|:----:|----|
|.|匹配除换行符以外的任意字符。|
|[ ]|字符类,匹配方括号中包含的任意字符。|
|[^ ]|否定字符类。匹配方括号中不包含的任意字符|
|*|匹配前面的子表达式零次或多次|
|+|匹配前面的子表达式一次或多次|
|?|匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。|
|{n,m}|花括号,匹配前面字符至少 n 次,但是不超过 m 次。|
|(xyz)|字符组,按照确切的顺序匹配字符xyz。|
|&#124;|分支结构,匹配符号之前的字符或后面的字符。|
|&#92;|转义符,它可以还原元字符原来的含义,允许你匹配保留字符 <code>[ ] ( ) { } . * + ? ^ $ \ &#124;</code>|
|^|匹配行的开始|
|$|匹配行的结束|
## 2.1 英文句号
英文句号 `.` 是元字符的最简单的例子。元字符 `.` 可以匹配任意单个字符。它不会匹配换行符和新行的字符。例如正则表达式 `.ar`,表示: 任意字符后面跟着一个字母 `a`
再后面跟着一个字母 `r`。<pre>".ar" => The <a href="#learn-regex"><strong>car</strong></a> <a href="#learn-regex"><strong>par</strong></a>ked in the <a href="#learn-regex"><strong>gar</strong></a>age.</pre>
## 2.2 字符集
字符集也称为字符类。方括号被用于指定字符集。使用字符集内的连字符来指定字符范围。方括号内的字符范围的顺序并不重要。
例如正则表达式 `[Tt]he`,表示: 大写 `T` 或小写 `t` ,后跟字母 `h`,再后跟字母 `e`。<pre>"[Tt]he" => <a href="#learn-regex"><strong>The</strong></a> car parked in <a href="#learn-regex"><strong>the</strong></a> garage.</pre>
然而,字符集中的英文句号表示它字面的含义。正则表达式 `ar[.]`,表示小写字母 `a`,后面跟着一个字母 `r`,再后面跟着一个英文句号 `.` 字符。<pre>"ar[.]" => A garage is a good place to park a c<a href="#learn-regex"><strong>ar.</strong></a></pre>
### 2.2.1 否定字符集
一般来说插入字符 `^` 表示一个字符串的开始,但是当它在方括号内出现时,它会取消字符集。例如正则表达式 `[^c]ar`,表示: 除了字母 `c` 以外的任意字符,后面跟着字符 `a`
再后面跟着一个字母 `r`。<pre>"[^c]ar" => The car <a href="#learn-regex"><strong>par</strong></a>ked in the <a href="#learn-regex"><strong>gar</strong></a>age.</pre>
## 2.3 重复
以下元字符 `+``*``?` 用于指定子模式可以出现多少次。这些元字符在不同情况下的作用不同。
### 2.3.1 星号
该符号 `*` 表示匹配上一个匹配规则的零次或多次。正则表达式 `a*` 表示小写字母 `a` 可以重复零次或者多次。但是它如果出现在字符集或者字符类之后,它表示整个字符集的重复。
例如正则表达式 `[a-z]*`,表示: 一行中可以包含任意数量的小写字母。<pre>"[a-z]*" => T<a href="#learn-regex"><strong>he</strong></a> <a href="#learn-regex"><strong>car</strong></a> <a href="#learn-regex"><strong>parked</strong></a> <a href="#learn-regex"><strong>in</strong></a> <a href="#learn-regex"><strong>the</strong></a> <a href="#learn-regex"><strong>garage</strong></a> #21.</pre>
`*` 符号可以与元符号 `.` 用在一起,用来匹配任意字符串 `.*`。该 `*` 符号可以与空格符 `\s` 一起使用,用来匹配一串空格字符。
例如正则表达式 `\s*cat\s*`,表示: 零个或多个空格,后面跟小写字母 `c`,再后面跟小写字母 `a`,再再后面跟小写字母 `t`,后面再跟零个或多个空格。<pre>"\s*cat\s*" => The fat<a href="#learn-regex"><strong> cat </strong></a>sat on the <a href="#learn-regex"><strong>cat</strong></a>.</pre>
### 2.3.2 加号
该符号 `+` 匹配上一个字符的一次或多次。例如正则表达式 `c.+t`,表示: 一个小写字母 `c`,后跟任意数量的字符,后跟小写字母 `t`。<pre>"c.+t" => The fat <a href="#learn-regex"><strong>cat sat on the mat</strong></a>.</pre>
### 2.3.3 问号
在正则表达式中,元字符 `?` 用来表示前一个字符是可选的。该符号匹配前一个字符的零次或一次。
例如正则表达式 `[T]?he`,表示: 可选的大写字母 `T`,后面跟小写字母 `h`,后跟小写字母 `e`。<pre>"[T]he" => <a href="#learn-regex"><strong>The</strong></a> car is parked in the garage.</pre><pre>"[T]?he" => <a href="#learn-regex"><strong>The</strong></a> car is parked in t<a href="#learn-regex"><strong>he</strong></a> garage.</pre>
## 2.4 花括号
在正则表达式中花括号(也被称为量词 ?)用于指定字符或一组字符可以重复的次数。例如正则表达式 `[0-9]{2,3}`,表示: 匹配至少2位数字但不超过3位(0到9范围内的字符)。<pre>"[0-9]{2,3}" => The number was 9.<a href="#learn-regex"><strong>999</strong></a>7 but we rounded it off to <a href="#learn-regex"><strong>10</strong></a>.0.</pre>
我们可以省略第二个数字。例如正则表达式 `[0-9]{2,}`,表示: 匹配2个或更多个数字。如果我们也删除逗号,则正则表达式 `[0-9]{2}`,表示: 匹配正好为2位数的数字。<pre>"[0-9]{2,}" => The number was 9.<a href="#learn-regex"><strong>9997</strong></a> but we rounded it off to <a href="#learn-regex"><strong>10</strong></a>.0.</pre><pre>"[0-9]{2}" => The number was 9.<a href="#learn-regex"><strong>99</strong></a><a href="#learn-regex"><strong>97</strong></a> but we rounded it off to <a href="#learn-regex"><strong>10</strong></a>.0.</pre>
## 2.5 字符组
字符组是一组写在圆括号内的子模式 `(...)`。正如我们在正则表达式中讨论的那样,如果我们把一个量词放在一个字符之后,它会重复前一个字符。
但是,如果我们把量词放在一个字符组之后,它会重复整个字符组。
例如正则表达式 `(ab)*` 表示匹配零个或多个的字符串 "ab"。我们还可以在字符组中使用元字符 `|`。例如正则表达式 `(c|g|p)ar`,表示: 小写字母 `c``g``p` 后面跟字母 `a`,后跟字母 `r`。<pre>"(c|g|p)ar" => The <a href="#learn-regex"><strong>car</strong></a> is <a href="#learn-regex"><strong>par</strong></a>ked in the <a href="#learn-regex"><strong>gar</strong></a>age.</pre>
## 2.6 分支结构
在正则表达式中垂直条 `|` 用来定义分支结构,分支结构就像多个表达式之间的条件。现在你可能认为这个字符集和分支机构的工作方式一样。
但是字符集和分支结构巨大的区别是字符集只在字符级别上有作用,然而分支结构在表达式级别上依然可以使用。
例如正则表达式 `(T|t)he|car`,表示: 大写字母 `T` 或小写字母 `t`,后面跟小写字母 `h`,后跟小写字母 `e` 或小写字母 `c`,后跟小写字母 `a`,后跟小写字母 `r`。<pre>"(T|t)he|car" => <a href="#learn-regex"><strong>The</strong></a> <a href="#learn-regex"><strong>car</strong></a> is parked in <a href="#learn-regex"><strong>the</strong></a> garage.</pre>
## 2.7 转义特殊字符
正则表达式中使用反斜杠 `\` 来转义下一个字符。这将允许你使用保留字符来作为匹配字符 `{ } [ ] / \ + * . $ ^ | ?`。在特殊字符前面加 `\`,就可以使用它来做匹配字符。
例如正则表达式 `.` 是用来匹配除了换行符以外的任意字符。现在要在输入字符串中匹配 `.` 字符,正则表达式 `(f|c|m)at\.?`,表示: 小写字母 `f``c` 或者 `m` 后跟小写字母 `a`,后跟小写字母 `t`,后跟可选的 `.` 字符。<pre>"(f|c|m)at\.?" => The <a href="#learn-regex"><strong>fat</strong></a> <a href="#learn-regex"><strong>cat</strong></a> sat on the <a href="#learn-regex"><strong>mat.</strong></a></pre>
## 2.8 定位符
在正则表达式中,为了检查匹配符号是否是起始符号或结尾符号,我们使用定位符。
定位符有两种类型: 第一种类型是 `^` 检查匹配字符是否是起始字符,第二种类型是 `$`,它检查匹配字符是否是输入字符串的最后一个字符。
### 2.8.1 插入符号
插入符号 `^` 符号用于检查匹配字符是否是输入字符串的第一个字符。如果我们使用正则表达式 `^a` (如果a是起始符号)匹配字符串 `abc`,它会匹配到 `a`
但是如果我们使用正则表达式 `^b`,它是匹配不到任何东西的,因为在字符串 `abc` 中 "b" 不是起始字符。
让我们来看看另一个正则表达式 `^(T|t)he`,这表示: 大写字母 `T` 或小写字母 `t` 是输入字符串的起始符号,后面跟着小写字母 `h`,后跟小写字母 `e`。<pre>"(T|t)he" => <a href="#learn-regex"><strong>The</strong></a> car is parked in <a href="#learn-regex"><strong>the</strong></a> garage.</pre><pre>"^(T|t)he" => <a href="#learn-regex"><strong>The</strong></a> car is parked in the garage.</pre>
### 2.8.2 美元符号
美元 `$` 符号用于检查匹配字符是否是输入字符串的最后一个字符。例如正则表达式 `(at\.)$`,表示: 小写字母 `a`,后跟小写字母 `t`,后跟一个 `.` 字符,且这个匹配器必须是字符串的结尾。<pre>"(at\.)" => The fat c<a href="#learn-regex"><strong>at.</strong></a> s<a href="#learn-regex"><strong>at.</strong></a> on the m<a href="#learn-regex"><strong>at.</strong></a></pre><pre>"(at\.)$" => The fat cat sat on the m<a href="#learn-regex"><strong>at.</strong></a></pre>
## 3. 简写字符集
正则表达式为常用的字符集和常用的正则表达式提供了简写。简写字符集如下:
|简写|描述|
|:----:|----|
|.|匹配除换行符以外的任意字符|
|\w|匹配所有字母和数字的字符: `[a-zA-Z0-9_]`|
|\W|匹配非字母和数字的字符: `[^\w]`|
|\d|匹配数字: `[0-9]`|
|\D|匹配非数字: `[^\d]`|
|\s|匹配空格符: `[\t\n\f\r\p{Z}]`|
|\S|匹配非空格符: `[^\s]`|
## 4. 断言
后行断言和先行断言有时候被称为断言,它们是特殊类型的 ***非捕获组*** (用于匹配模式,但不包括在匹配列表中)。当我们在一种特定模式之前或者之后有这种模式时,会优先使用断言。
例如我们想获取输入字符串 `$4.44 and $10.88` 中带有前缀 `$` 的所有数字。我们可以使用这个正则表达式 `(?<=\$)[0-9\.]*`,表示: 获取包含 `.` 字符且前缀为 `$` 的所有数字。
以下是正则表达式中使用的断言:
|符号|描述|
|:----:|----|
|?=|正向先行断言|
|?!|负向先行断言|
|?<=|正向后行断言|
|?<!|负向后行断言|
### 4.1 正向先行断言
正向先行断言认为第一部分的表达式必须是先行断言表达式。返回的匹配结果仅包含与第一部分表达式匹配的文本。
要在一个括号内定义一个正向先行断言,在括号中问号和等号是这样使用的 `(?=...)`。先行断言表达式写在括号中的等号后面。
例如正则表达式 `(T|t)he(?=\sfat)`,表示: 匹配大写字母 `T` 或小写字母 `t`,后面跟字母 `h`,后跟字母 `e`
在括号中,我们定义了正向先行断言,它会引导正则表达式引擎匹配 `The``the` 后面跟着 `fat`。<pre>"(T|t)he(?=\sfat)" => <a href="#learn-regex"><strong>The</strong></a> fat cat sat on the mat.</pre>
### 4.2 负向先行断言
当我们需要从输入字符串中获取不匹配表达式的内容时,使用负向先行断言。负向先行断言的定义跟我们定义的正向先行断言一样,
唯一的区别是不是等号 `=`,我们使用否定符号 `!`,例如 `(?!...)`
我们来看看下面的正则表达式 `(T|t)he(?!\sfat)`,表示: 从输入字符串中获取全部 `The` 或者 `the` 且不匹配 `fat` 前面加上一个空格字符。<pre>"(T|t)he(?!\sfat)" => The fat cat sat on <a href="#learn-regex"><strong>the</strong></a> mat.</pre>
### 4.3 正向后行断言
正向后行断言是用于获取在特定模式之前的所有匹配内容。正向后行断言表示为 `(?<=...)`。例如正则表达式 `(?<=(T|t)he\s)(fat|mat)`,表示: 从输入字符串中获取在单词 `The``the` 之后的所有 `fat``mat` 单词。<pre>"(?<=(T|t)he\s)(fat|mat)" => The <a href="#learn-regex"><strong>fat</strong></a> cat sat on the <a href="#learn-regex"><strong>mat</strong></a>.</pre>
### 4.4 负向后行断言
负向后行断言是用于获取不在特定模式之前的所有匹配的内容。负向后行断言表示为 `(?<!...)`。例如正则表达式 `(?<!(T|t)he\s)(cat)`,表示: 在输入字符中获取所有不在 `The``the` 之后的所有单词 `cat`。<pre>"(?&lt;!(T|t)he\s)(cat)" => The cat sat on <a href="#learn-regex"><strong>cat</strong></a>.</pre>
## 5. 标记
标记也称为修饰符,因为它会修改正则表达式的输出。这些标志可以以任意顺序或组合使用,并且是正则表达式的一部分。
|标记|描述|
|:----:|----|
|i|不区分大小写: 将匹配设置为不区分大小写。|
|g|全局搜索: 搜索整个输入字符串中的所有匹配。|
|m|多行匹配: 会匹配输入字符串每一行。|
* **数字**: `\d+$`
* **用户名**: `^[\w\d_.]{4,16}$`
* **字母数字字符**: `^[a-zA-Z0-9]*$`
* **带空格的字母数字字符**: `^[a-zA-Z0-9 ]*$`
* **小写字母**: `[a-z]+$`
* **大写字母**: `[A-Z]+$`
* **网址**: `^(((http|https|ftp):\/\/)?([[a-zA-Z0-9]\-\.])+(\.)([[a-zA-Z0-9]]){2,4}([[a-zA-Z0-9]\/+=%&_\.~?\-]*))*$`
* **日期 (MM/DD/YYYY)**: `^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}$`
* **日期 (YYYY/MM/DD)**: `^(19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])$`
* **求更求转发致谢**: `[\((【].*?[求更谢乐发推].*?[】)\)]`
* **查找最新章节**: `您可以.*?查找最新章节`
* **ps/PS**: `(?i)ps\b.*`
* **Html标签**: `<[^>]+?>`

Some files were not shown because too many files have changed in this diff Show More