Skip to content

Commit 07a14b0

Browse files
committed
[feature] 轻量级插件 30%
1 parent 8160bd8 commit 07a14b0

15 files changed

+655
-274
lines changed

app/src/main/java/com/heyanle/easybangumi4/cartoon/story/download/step/TransformerStep.kt

+5-3
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ object TransformerStep : BaseStep {
126126
} else {
127127
runtime.transformerProgress = -1
128128
}
129-
130-
131-
val speed = runtime.updateSeedPreSecond(t.length(), System.currentTimeMillis())
132129
runtime.transformerProgress.logi("TransformerStep")
133130
runtime.dispatchToBus(
134131
runtime.transformerProgress.toFloat() / 100f,
@@ -147,6 +144,11 @@ object TransformerStep : BaseStep {
147144
}
148145

149146
}
147+
if (runtime.needCancel()) {
148+
runtime.error(runtime.exportException, runtime.exportException?.message)
149+
return
150+
}
151+
150152
runtime.stepCompletely()
151153
}
152154

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.heyanle.easybangumi4.plugin.js.component
2+
3+
import com.heyanle.easybangumi4.plugin.js.runtime.JSScope
4+
import com.heyanle.easybangumi4.source_api.SourceResult
5+
import com.heyanle.easybangumi4.source_api.component.ComponentWrapper
6+
import com.heyanle.easybangumi4.source_api.component.detailed.DetailedComponent
7+
import com.heyanle.easybangumi4.source_api.entity.Cartoon
8+
import com.heyanle.easybangumi4.source_api.entity.CartoonSummary
9+
import com.heyanle.easybangumi4.source_api.entity.PlayLine
10+
import org.mozilla.javascript.Function
11+
12+
/**
13+
* Created by heyanle on 2024/7/28.
14+
* https://github.com/heyanLE
15+
*/
16+
class JSDetailedComponent(
17+
private val jsScope: JSScope,
18+
private val getDetailed: Function,
19+
): ComponentWrapper(), DetailedComponent {
20+
21+
companion object {
22+
const val FUNCTION_NAME_GET_DETAILED = "DetailedComponent_getDetailed"
23+
24+
suspend fun of (jsScope: JSScope) : JSDetailedComponent ? {
25+
return jsScope.runWithScope { _, scriptable ->
26+
val getDetailed = scriptable.get(FUNCTION_NAME_GET_DETAILED, scriptable) as? Function
27+
?: return@runWithScope null
28+
return@runWithScope JSDetailedComponent(jsScope, getDetailed)
29+
}
30+
}
31+
}
32+
33+
override suspend fun getAll(summary: CartoonSummary): SourceResult<Pair<Cartoon, List<PlayLine>>> {
34+
TODO("Not yet implemented")
35+
}
36+
37+
override suspend fun getDetailed(summary: CartoonSummary): SourceResult<Cartoon> {
38+
TODO("Not yet implemented")
39+
}
40+
41+
override suspend fun getPlayLine(summary: CartoonSummary): SourceResult<List<PlayLine>> {
42+
TODO("Not yet implemented")
43+
}
44+
}

app/src/main/java/com/heyanle/easybangumi4/plugin/js/component/JSPageComponent.kt

+25-10
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,47 @@
11
package com.heyanle.easybangumi4.plugin.js.component
22

33
import androidx.annotation.WorkerThread
4+
import com.heyanle.easybangumi4.plugin.js.runtime.JSScope
45
import com.heyanle.easybangumi4.source_api.Source
56
import com.heyanle.easybangumi4.source_api.component.ComponentWrapper
67
import com.heyanle.easybangumi4.source_api.component.page.PageComponent
78
import com.heyanle.easybangumi4.source_api.component.page.SourcePage
9+
import org.mozilla.javascript.Function
810
import org.mozilla.javascript.ScriptableObject
911
import org.mozilla.javascript.Context as JSContext
1012

1113
/**
1214
* Created by heyanle on 2024/7/27.
1315
* https://github.com/heyanLE
1416
*/
15-
class JSPageComponent: ComponentWrapper(), PageComponent {
17+
class JSPageComponent(
18+
private val jsScope: JSScope,
19+
private val getMainTabs: Function,
20+
private val getSubTabs: Function,
21+
private val initPageKey: Function,
22+
private val getContent: Function,
23+
): ComponentWrapper(), PageComponent {
1624

1725

1826
companion object {
1927

20-
const val CheckJsCode = """
21-
typeof PageComponent_getMainTabs == 'function' &&
22-
typeof PageComponent_getSubTabs == 'function' &&
23-
typeof PageComponent_initPageKey == 'function' &&
24-
typeof PageComponent_getContent == 'function'
25-
"""
2628

27-
@WorkerThread
28-
fun check( jsContext: JSContext, scope: ScriptableObject) {
29-
jsContext.evaluateString(scope, CheckJsCode, null, 1, null)
29+
const val FUNCTION_NAME_GET_MAIN_TABS = "PageComponent_getMainTabs"
30+
const val FUNCTION_NAME_GET_SUB_TABS = "PageComponent_getSubTabs"
31+
const val FUNCTION_NAME_INIT_PAGE_KEY = "PageComponent_initPageKey"
32+
const val FUNCTION_NAME_GET_CONTENT = "PageComponent_getContent"
33+
34+
suspend fun of (jsScope: JSScope) : JSPageComponent ? {
35+
return jsScope.runWithScope { _, scriptable ->
36+
val getMainTabs = scriptable.get(FUNCTION_NAME_GET_MAIN_TABS, scriptable) as? Function
37+
val getSubTabs = scriptable.get(FUNCTION_NAME_GET_SUB_TABS, scriptable) as? Function
38+
val initPageKey = scriptable.get(FUNCTION_NAME_INIT_PAGE_KEY, scriptable) as? Function
39+
val getContent = scriptable.get(FUNCTION_NAME_GET_CONTENT, scriptable) as? Function
40+
if(getMainTabs == null || getSubTabs == null || initPageKey == null || getContent == null){
41+
return@runWithScope null
42+
}
43+
return@runWithScope JSPageComponent(jsScope, getMainTabs, getSubTabs, initPageKey, getContent)
44+
}
3045
}
3146
}
3247

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.heyanle.easybangumi4.plugin.js.component
2+
3+
import com.heyanle.easybangumi4.plugin.js.runtime.JSScope
4+
import com.heyanle.easybangumi4.source_api.SourceResult
5+
import com.heyanle.easybangumi4.source_api.component.ComponentWrapper
6+
import com.heyanle.easybangumi4.source_api.component.play.PlayComponent
7+
import com.heyanle.easybangumi4.source_api.entity.CartoonSummary
8+
import com.heyanle.easybangumi4.source_api.entity.Episode
9+
import com.heyanle.easybangumi4.source_api.entity.PlayLine
10+
import com.heyanle.easybangumi4.source_api.entity.PlayerInfo
11+
import org.mozilla.javascript.Function
12+
13+
/**
14+
* Created by heyanle on 2024/7/28.
15+
* https://github.com/heyanLE
16+
*/
17+
class JSPlayComponent(
18+
private val jsScope: JSScope,
19+
private val getPlayInfo: Function,
20+
): ComponentWrapper(), PlayComponent {
21+
22+
companion object {
23+
const val FUNCTION_NAME_GET_PLAY_INFO = "PlayComponent_getPlayInfo"
24+
25+
suspend fun of (jsScope: JSScope) : JSPlayComponent ? {
26+
return jsScope.runWithScope { _, scriptable ->
27+
val getPlayInfo = scriptable.get(FUNCTION_NAME_GET_PLAY_INFO, scriptable) as? Function
28+
?: return@runWithScope null
29+
return@runWithScope JSPlayComponent(jsScope, getPlayInfo)
30+
}
31+
}
32+
33+
}
34+
35+
override suspend fun getPlayInfo(
36+
summary: CartoonSummary,
37+
playLine: PlayLine,
38+
episode: Episode
39+
): SourceResult<PlayerInfo> {
40+
TODO("Not yet implemented")
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.heyanle.easybangumi4.plugin.js.component
2+
3+
import com.heyanle.easybangumi4.plugin.js.runtime.JSScope
4+
import com.heyanle.easybangumi4.source_api.component.ComponentWrapper
5+
import com.heyanle.easybangumi4.source_api.component.preference.PreferenceComponent
6+
import com.heyanle.easybangumi4.source_api.component.preference.SourcePreference
7+
import org.mozilla.javascript.Function
8+
9+
/**
10+
* Created by heyanle on 2024/7/28.
11+
* https://github.com/heyanLE
12+
*/
13+
class JSPreferenceComponent(
14+
private val jsScope: JSScope,
15+
private val getPreference: Function,
16+
): ComponentWrapper(), PreferenceComponent {
17+
18+
companion object {
19+
const val FUNCTION_NAME_GET_PREFERENCE = "PreferenceComponent_getPreference"
20+
21+
suspend fun of (jsScope: JSScope) : JSPreferenceComponent ? {
22+
return jsScope.runWithScope { _, scriptable ->
23+
val getPreference = scriptable.get(FUNCTION_NAME_GET_PREFERENCE, scriptable) as? Function
24+
?: return@runWithScope null
25+
return@runWithScope JSPreferenceComponent(jsScope, getPreference)
26+
}
27+
}
28+
}
29+
30+
31+
32+
override fun register(): List<SourcePreference> {
33+
TODO("Not yet implemented")
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.heyanle.easybangumi4.plugin.js.component
2+
3+
import com.heyanle.easybangumi4.plugin.js.runtime.JSScope
4+
import com.heyanle.easybangumi4.source_api.SourceResult
5+
import com.heyanle.easybangumi4.source_api.component.ComponentWrapper
6+
import com.heyanle.easybangumi4.source_api.component.search.SearchComponent
7+
import com.heyanle.easybangumi4.source_api.entity.CartoonCover
8+
import org.mozilla.javascript.Function
9+
10+
/**
11+
* Created by heyanle on 2024/7/28.
12+
* https://github.com/heyanLE
13+
*/
14+
class JSSearchComponent(
15+
private val jsScope: JSScope,
16+
private val search: Function,
17+
): ComponentWrapper(), SearchComponent {
18+
19+
companion object {
20+
const val FUNCTION_NAME_SEARCH = "SearchComponent_search"
21+
22+
suspend fun of (jsScope: JSScope) : JSSearchComponent ? {
23+
return jsScope.runWithScope { _, scriptable ->
24+
val search = scriptable.get(FUNCTION_NAME_SEARCH, scriptable) as? Function
25+
?: return@runWithScope null
26+
return@runWithScope JSSearchComponent(jsScope, search)
27+
}
28+
}
29+
}
30+
31+
32+
// 这里因为不支持异步,因此强迫从 0 开始,交给 js 端处理
33+
override fun getFirstSearchKey(keyword: String): Int {
34+
return 0
35+
}
36+
37+
override suspend fun search(
38+
pageKey: Int,
39+
keyword: String
40+
): SourceResult<Pair<Int?, List<CartoonCover>>> {
41+
TODO("Not yet implemented")
42+
}
43+
}

app/src/main/java/com/heyanle/easybangumi4/plugin/js/extension/JSExtensionLoader.kt

+34-43
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package com.heyanle.easybangumi4.plugin.js.extension
33
import com.heyanle.easybangumi4.plugin.extension.ExtensionInfo
44
import com.heyanle.easybangumi4.plugin.extension.loader.ExtensionLoader
55
import com.heyanle.easybangumi4.plugin.js.runtime.JSRuntime
6+
import com.heyanle.easybangumi4.plugin.js.runtime.JSScope
7+
import com.heyanle.easybangumi4.plugin.js.source.JsSource
68
import java.io.File
79

810
/**
@@ -11,6 +13,7 @@ import java.io.File
1113
*/
1214
class JSExtensionLoader(
1315
private val file: File,
16+
private val jsRuntime: JSRuntime,
1417
): ExtensionLoader {
1518

1619
companion object {
@@ -40,56 +43,44 @@ class JSExtensionLoader(
4043

4144
val map = HashMap<String, String>()
4245

43-
val lineList = file.readLines()
44-
for (line in lineList) {
45-
if (line.isEmpty() || !line.startsWith("//")){
46-
break
47-
}
48-
49-
var firstAtIndex = -1
50-
var spacerAfterAtIndex = -1
51-
52-
line.forEachIndexed { index, c ->
53-
if (firstAtIndex == -1 && c != '@'){
54-
firstAtIndex = index
46+
file.reader().buffered().use {
47+
var line = it.readLine()
48+
while(line != null) {
49+
if (line.isEmpty() || !line.startsWith("//")){
50+
break
5551
}
56-
if (firstAtIndex != -1 && spacerAfterAtIndex == -1 && c == ' '){
57-
spacerAfterAtIndex = index
52+
var firstAtIndex = -1
53+
var spacerAfterAtIndex = -1
54+
55+
line.forEachIndexed { index, c ->
56+
if (firstAtIndex == -1 && c != '@'){
57+
firstAtIndex = index
58+
}
59+
if (firstAtIndex != -1 && spacerAfterAtIndex == -1 && c == ' '){
60+
spacerAfterAtIndex = index
61+
}
62+
if (firstAtIndex != -1 && spacerAfterAtIndex != -1){
63+
return@forEachIndexed
64+
}
5865
}
59-
if (firstAtIndex != -1 && spacerAfterAtIndex != -1){
60-
return@forEachIndexed
66+
67+
if (firstAtIndex == -1 || spacerAfterAtIndex == -1){
68+
continue
6169
}
62-
}
6370

64-
if (firstAtIndex == -1 || spacerAfterAtIndex == -1){
65-
continue
71+
val key = line.substring(firstAtIndex + 1, spacerAfterAtIndex)
72+
val value = line.substring(spacerAfterAtIndex + 1)
73+
map[key] = value
74+
line = it.readLine()
6675
}
67-
68-
val key = line.substring(firstAtIndex + 1, spacerAfterAtIndex)
69-
val value = line.substring(spacerAfterAtIndex + 1)
70-
map[key] = value
7176
}
72-
val text = lineList.joinToString("\n")
73-
val jsRuntime = JSRuntime()
74-
jsRuntime.init()
75-
jsRuntime.postWithScope { context, scriptableObject ->
76-
context.evaluateString(
77-
scriptableObject,
78-
JS_IMPORT,
79-
null,
80-
1,
81-
null
82-
83-
)
84-
context.evaluateString(
85-
scriptableObject,
86-
text,
87-
null,
88-
1,
89-
null
90-
)
9177

92-
}
78+
val jsScope = JSScope(jsRuntime)
79+
val source = JsSource(
80+
map,
81+
file,
82+
jsScope
83+
)
9384

9485
return null
9586

app/src/main/java/com/heyanle/easybangumi4/plugin/js/runtime/JSScope.kt

+6
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,11 @@ class JSScope(
2525
}
2626
}
2727

28+
suspend fun <R> runWithScope(block: (JSContext, Scriptable) -> R) : R? {
29+
return jsRuntime.runWithScope { ctx, scope ->
30+
block(ctx, scriptable)
31+
}
32+
}
33+
2834

2935
}

0 commit comments

Comments
 (0)