mirror of
https://github.com/Aminark/legado-ios.git
synced 2026-10-24 21:01:22 +08:00
支持 EPUB 2/3 导入、目录、封面和章节插图,保留本地书管理与阅读进度。 修复 JSON 模板、动态替换与请求参数兼容,以及 RSS 翻页和连续滚动定位。 更新编辑器工具栏和回归测试,发布版本为 0.1.12(build 18)。
90 lines
5.1 KiB
Swift
90 lines
5.1 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import LegadoCore
|
|
|
|
// Opt-in only: point LEGADO_SOURCE_PROBE_FILE at a downloaded JSON source pack.
|
|
// No remote source or response is included in the application or normal test run.
|
|
struct BookSourceRemoteProbe {
|
|
@Test(.enabled(if: ProcessInfo.processInfo.environment["LEGADO_SOURCE_CHAIN_FILE"] != nil))
|
|
func sampleReadingPipelines() async throws {
|
|
let path = try #require(ProcessInfo.processInfo.environment["LEGADO_SOURCE_CHAIN_FILE"])
|
|
let sources = try BookSourceImporter().decode(Data(contentsOf: URL(fileURLWithPath: path)))
|
|
var reports: [BookSourceDebugReport] = []
|
|
let transport = ProbeTransport()
|
|
let keyword = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_KEYWORD"] ?? "斗罗大陆"
|
|
for source in sources {
|
|
var report = await BookSourceDebugger(transport: transport).run(source: source, keyword: keyword)
|
|
report.contentPreview = nil
|
|
reports.append(report)
|
|
print("SOURCE_CHAIN \(source.bookSourceName) " + String(decoding: try JSONEncoder().encode(report), as: UTF8.self))
|
|
}
|
|
if let output = ProcessInfo.processInfo.environment["LEGADO_SOURCE_CHAIN_OUTPUT"] {
|
|
try JSONEncoder().encode(reports).write(to: URL(fileURLWithPath: output))
|
|
try JSONEncoder().encode(await transport.records()).write(to: URL(fileURLWithPath: output + ".requests.json"))
|
|
}
|
|
#expect(reports.count == sources.count)
|
|
}
|
|
|
|
@Test(.enabled(if: ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_FILE"] != nil))
|
|
func sampleSearches() async throws {
|
|
guard let path = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_FILE"] else { return }
|
|
let sources = try BookSourceImporter().decode(Data(contentsOf: URL(fileURLWithPath: path)))
|
|
let transport = ProbeTransport()
|
|
let service = BookSearchService(transport: transport, networkPolicy: .init(), history: .init())
|
|
let keyword = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_KEYWORD"] ?? "斗罗大陆"
|
|
let page = Int(ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_PAGE"] ?? "1") ?? 1
|
|
var rows: [[String: JSONValue]] = []
|
|
for await outcome in service.searchOutcomes(keyword: keyword, page: page, sources: sources, maximumConcurrentSources: 3, includeDisabled: true) {
|
|
let source = try #require(sources.first { $0.id == outcome.sourceID })
|
|
let row: [String: JSONValue] = [
|
|
"name": .string(source.bookSourceName), "source": .string(source.id),
|
|
"count": .number(Double(outcome.books.count)),
|
|
"books": .array(outcome.books.prefix(3).map { .object([
|
|
"name": .string($0.name), "url": .string($0.bookURL), "author": .string($0.author),
|
|
"cover": .string($0.coverURL ?? ""), "wordCount": .string($0.wordCount ?? "")
|
|
]) }),
|
|
"diagnostics": .array(outcome.diagnostics.map { .object(["code": .string($0.code), "message": .string($0.message), "rule": .string($0.rule)]) })
|
|
]
|
|
rows.append(row)
|
|
print("SOURCE_PROBE " + JSONValue.object(row).stringValue)
|
|
}
|
|
let report = JSONValue.object(["keyword": .string(keyword), "page": .number(Double(page)), "outcomes": .array(rows.map(JSONValue.object)), "requests": .array(await transport.records())])
|
|
if let output = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_OUTPUT"] {
|
|
try JSONEncoder().encode(report).write(to: URL(fileURLWithPath: output))
|
|
}
|
|
#expect(rows.count == Set(sources.map(\.id)).count)
|
|
}
|
|
}
|
|
|
|
private actor ProbeTransport: HTTPTransport {
|
|
private var values: [JSONValue] = []
|
|
private let transport = URLSessionHTTPTransport()
|
|
|
|
func data(for request: URLRequest) async throws -> HTTPResponse {
|
|
do {
|
|
let response = try await transport.data(for: request)
|
|
var record: [String: JSONValue] = [
|
|
"url": .string(request.url?.absoluteString ?? ""),
|
|
"finalURL": .string(response.finalURL.absoluteString),
|
|
"status": .number(Double(response.statusCode)),
|
|
"bytes": .number(Double(response.data.count)),
|
|
"preview": .string(String(response.decodedText.prefix(240)))
|
|
]
|
|
if let directory = ProcessInfo.processInfo.environment["LEGADO_SOURCE_PROBE_SNAPSHOT_DIR"] {
|
|
let folder = URL(fileURLWithPath: directory, isDirectory: true)
|
|
try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
|
|
let file = folder.appendingPathComponent(UUID().uuidString + ".response")
|
|
try response.data.write(to: file)
|
|
record["snapshot"] = .string(file.path)
|
|
}
|
|
values.append(.object(record))
|
|
return response
|
|
} catch {
|
|
values.append(.object(["url": .string(request.url?.absoluteString ?? ""), "error": .string(error.localizedDescription)]))
|
|
throw error
|
|
}
|
|
}
|
|
|
|
func records() -> [JSONValue] { values }
|
|
}
|