more logging and stuff

This commit is contained in:
Seiike 2025-01-23 02:09:49 +01:00
parent 9a8ea5f94d
commit db2eae3819
7 changed files with 54 additions and 49 deletions

View file

@ -17,31 +17,31 @@ class JSController: ObservableObject {
private func setupContext() {
let logFunction: @convention(block) (String) -> Void = { message in
Logger.shared.log("JavaScript log: \(message)")
Logger.shared.log("JavaScript log: \(message)", type: "Debug")
}
context.setObject(logFunction, forKeyedSubscript: "log" as NSString)
let fetchNativeFunction: @convention(block) (String, JSValue, JSValue) -> Void = { urlString, resolve, reject in
guard let url = URL(string: urlString) else {
Logger.shared.log("Invalid URL")
Logger.shared.log("Invalid URL",type: "Error")
reject.call(withArguments: ["Invalid URL"])
return
}
let task = URLSession.custom.dataTask(with: url) { data, _, error in
if let error = error {
Logger.shared.log("Network error in fetchNativeFunction: \(error.localizedDescription)")
Logger.shared.log("Network error in fetchNativeFunction: \(error.localizedDescription)",type: "Error")
reject.call(withArguments: [error.localizedDescription])
return
}
guard let data = data else {
Logger.shared.log("No data in response")
Logger.shared.log("No data in response",type: "Error")
reject.call(withArguments: ["No data"])
return
}
if let text = String(data: data, encoding: .utf8) {
resolve.call(withArguments: [text])
} else {
Logger.shared.log("Unable to decode data to text")
Logger.shared.log("Unable to decode data to text",type: "Error")
reject.call(withArguments: ["Unable to decode data"])
}
}
@ -77,18 +77,18 @@ class JSController: ObservableObject {
guard let self = self else { return }
if let error = error {
Logger.shared.log("Network error: \(error)")
Logger.shared.log("Network error: \(error)",type: "Error")
DispatchQueue.main.async { completion([]) }
return
}
guard let data = data, let html = String(data: data, encoding: .utf8) else {
Logger.shared.log("Failed to decode HTML")
Logger.shared.log("Failed to decode HTML",type: "Error")
DispatchQueue.main.async { completion([]) }
return
}
Logger.shared.log(html)
Logger.shared.log(html,type: "Debug")
if let parseFunction = self.context.objectForKeyedSubscript("searchResults"),
let results = parseFunction.call(withArguments: [html]).toArray() as? [[String: String]] {
let resultItems = results.map { item in
@ -102,7 +102,7 @@ class JSController: ObservableObject {
completion(resultItems)
}
} else {
Logger.shared.log("Failed to parse results")
Logger.shared.log("Failed to parse results",type: "Error")
DispatchQueue.main.async { completion([]) }
}
}.resume()
@ -118,13 +118,13 @@ class JSController: ObservableObject {
guard let self = self else { return }
if let error = error {
Logger.shared.log("Network error: \(error)")
Logger.shared.log("Network error: \(error)",type: "Error")
DispatchQueue.main.async { completion([], []) }
return
}
guard let data = data, let html = String(data: data, encoding: .utf8) else {
Logger.shared.log("Failed to decode HTML")
Logger.shared.log("Failed to decode HTML",type: "Error")
DispatchQueue.main.async { completion([], []) }
return
}
@ -132,7 +132,7 @@ class JSController: ObservableObject {
var resultItems: [MediaItem] = []
var episodeLinks: [EpisodeLink] = []
Logger.shared.log(html)
Logger.shared.log(html,type: "Debug")
if let parseFunction = self.context.objectForKeyedSubscript("extractDetails"),
let results = parseFunction.call(withArguments: [html]).toArray() as? [[String: String]] {
resultItems = results.map { item in
@ -143,7 +143,7 @@ class JSController: ObservableObject {
)
}
} else {
Logger.shared.log("Failed to parse results")
Logger.shared.log("Failed to parse results",type: "Error")
}
if let fetchEpisodesFunction = self.context.objectForKeyedSubscript("extractEpisodes"),
@ -171,25 +171,26 @@ class JSController: ObservableObject {
guard let self = self else { return }
if let error = error {
Logger.shared.log("Network error: \(error)")
Logger.shared.log("Network error: \(error)",type: "Error")
DispatchQueue.main.async { completion(nil) }
return
}
guard let data = data, let html = String(data: data, encoding: .utf8) else {
Logger.shared.log("Failed to decode HTML")
Logger.shared.log("Failed to decode HTML",type: "Error")
DispatchQueue.main.async { completion(nil) }
return
}
Logger.shared.log(html)
Logger.shared.log(html,type: "Debug")
if let parseFunction = self.context.objectForKeyedSubscript("extractStreamUrl"),
let streamUrl = parseFunction.call(withArguments: [html]).toString() {
Logger.shared.log("Staring stream from: \(streamUrl)", type: "Stream")
DispatchQueue.main.async {
completion(streamUrl)
}
} else {
Logger.shared.log("Failed to extract stream URL")
Logger.shared.log("Failed to extract stream URL",type: "Error")
DispatchQueue.main.async { completion(nil) }
}
}.resume()
@ -197,27 +198,27 @@ class JSController: ObservableObject {
func fetchJsSearchResults(keyword: String, module: ScrapingModule, completion: @escaping ([SearchItem]) -> Void) {
if let exception = context.exception {
Logger.shared.log("JavaScript exception: \(exception)")
Logger.shared.log("JavaScript exception: \(exception)",type: "Error")
completion([])
return
}
guard let searchResultsFunction = context.objectForKeyedSubscript("searchResults") else {
Logger.shared.log("No JavaScript function searchResults found")
Logger.shared.log("No JavaScript function searchResults found",type: "Error")
completion([])
return
}
let promiseValue = searchResultsFunction.call(withArguments: [keyword])
guard let promise = promiseValue else {
Logger.shared.log("searchResults did not return a Promise")
Logger.shared.log("searchResults did not return a Promise",type: "Error")
completion([])
return
}
let thenBlock: @convention(block) (JSValue) -> Void = { result in
Logger.shared.log(result.toString())
Logger.shared.log(result.toString(),type: "Debug")
if let jsonString = result.toString(),
let data = jsonString.data(using: .utf8) {
do {
@ -234,19 +235,19 @@ class JSController: ObservableObject {
}
} else {
Logger.shared.log("Failed to parse JSON")
Logger.shared.log("Failed to parse JSON",type: "Error")
DispatchQueue.main.async {
completion([])
}
}
} catch {
Logger.shared.log("JSON parsing error: \(error)")
Logger.shared.log("JSON parsing error: \(error)",type: "Error")
DispatchQueue.main.async {
completion([])
}
}
} else {
Logger.shared.log("Result is not a string")
Logger.shared.log("Result is not a string",type: "Error")
DispatchQueue.main.async {
completion([])
}
@ -254,7 +255,7 @@ class JSController: ObservableObject {
}
let catchBlock: @convention(block) (JSValue) -> Void = { error in
Logger.shared.log("Promise rejected: \(String(describing: error.toString()))")
Logger.shared.log("Promise rejected: \(String(describing: error.toString()))",type: "Error")
DispatchQueue.main.async {
completion([])
}
@ -274,19 +275,19 @@ class JSController: ObservableObject {
}
if let exception = context.exception {
Logger.shared.log("JavaScript exception: \(exception)")
Logger.shared.log("JavaScript exception: \(exception)",type: "Error")
completion([], [])
return
}
guard let extractDetailsFunction = context.objectForKeyedSubscript("extractDetails") else {
Logger.shared.log("No JavaScript function extractDetails found")
Logger.shared.log("No JavaScript function extractDetails found",type: "Error")
completion([], [])
return
}
guard let extractEpisodesFunction = context.objectForKeyedSubscript("extractEpisodes") else {
Logger.shared.log("No JavaScript function extractEpisodes found")
Logger.shared.log("No JavaScript function extractEpisodes found",type: "Error")
completion([], [])
return
}
@ -299,13 +300,13 @@ class JSController: ObservableObject {
dispatchGroup.enter()
let promiseValueDetails = extractDetailsFunction.call(withArguments: [url.absoluteString])
guard let promiseDetails = promiseValueDetails else {
Logger.shared.log("extractDetails did not return a Promise")
Logger.shared.log("extractDetails did not return a Promise",type: "Error")
completion([], [])
return
}
let thenBlockDetails: @convention(block) (JSValue) -> Void = { result in
Logger.shared.log(result.toString())
Logger.shared.log(result.toString(),type: "Debug")
if let jsonOfDetails = result.toString(),
let dataDetails = jsonOfDetails.data(using: .utf8) {
do {
@ -318,19 +319,19 @@ class JSController: ObservableObject {
)
}
} else {
Logger.shared.log("Failed to parse JSON of extractDetails")
Logger.shared.log("Failed to parse JSON of extractDetails",type: "Error")
}
} catch {
Logger.shared.log("JSON parsing error of extract details: \(error)")
Logger.shared.log("JSON parsing error of extract details: \(error)",type: "Error")
}
} else {
Logger.shared.log("Result is not a string of extractDetails")
Logger.shared.log("Result is not a string of extractDetails",type: "Error")
}
dispatchGroup.leave()
}
let catchBlockDetails: @convention(block) (JSValue) -> Void = { error in
Logger.shared.log("Promise rejected of extractDetails: \(String(describing: error.toString()))")
Logger.shared.log("Promise rejected of extractDetails: \(String(describing: error.toString()))",type: "Error")
dispatchGroup.leave()
}
@ -343,13 +344,13 @@ class JSController: ObservableObject {
dispatchGroup.enter()
let promiseValueEpisodes = extractEpisodesFunction.call(withArguments: [url.absoluteString])
guard let promiseEpisodes = promiseValueEpisodes else {
Logger.shared.log("extractEpisodes did not return a Promise")
Logger.shared.log("extractEpisodes did not return a Promise",type: "Error")
completion([], [])
return
}
let thenBlockEpisodes: @convention(block) (JSValue) -> Void = { result in
Logger.shared.log(result.toString())
Logger.shared.log(result.toString(),type: "Debug")
if let jsonOfEpisodes = result.toString(),
let dataEpisodes = jsonOfEpisodes.data(using: .utf8) {
do {
@ -361,19 +362,19 @@ class JSController: ObservableObject {
)
}
} else {
Logger.shared.log("Failed to parse JSON of extractEpisodes")
Logger.shared.log("Failed to parse JSON of extractEpisodes",type: "Error")
}
} catch {
Logger.shared.log("JSON parsing error of extractEpisodes: \(error)")
Logger.shared.log("JSON parsing error of extractEpisodes: \(error)",type: "Error")
}
} else {
Logger.shared.log("Result is not a string of extractEpisodes")
Logger.shared.log("Result is not a string of extractEpisodes",type: "Error")
}
dispatchGroup.leave()
}
let catchBlockEpisodes: @convention(block) (JSValue) -> Void = { error in
Logger.shared.log("Promise rejected of extractEpisodes: \(String(describing: error.toString()))")
Logger.shared.log("Promise rejected of extractEpisodes: \(String(describing: error.toString()))",type: "Error")
dispatchGroup.leave()
}

View file

@ -103,7 +103,7 @@ struct EpisodeCell: View {
URLSession.custom.dataTask(with: url) { data, _, error in
if let error = error {
Logger.shared.log("Failed to fetch episode details: \(error)")
Logger.shared.log("Failed to fetch episode details: \(error)", type: "Error")
DispatchQueue.main.async {
self.isLoading = false
}
@ -133,7 +133,7 @@ struct EpisodeCell: View {
let episodeDetails = episodes["\(episodeID + 1)"] as? [String: Any],
let title = episodeDetails["title"] as? [String: String],
let image = episodeDetails["image"] as? String else {
Logger.shared.log("Invalid response format")
Logger.shared.log("Invalid response format", type: "Error")
DispatchQueue.main.async {
self.isLoading = false
}
@ -146,7 +146,7 @@ struct EpisodeCell: View {
self.isLoading = false
}
} catch {
Logger.shared.log("Failed to parse JSON: \(error)")
Logger.shared.log("Failed to parse JSON: \(error)", type: "Error")
DispatchQueue.main.async {
self.isLoading = false
}

View file

@ -224,7 +224,7 @@ struct MediaInfoView: View {
}
}
} catch {
Logger.shared.log("Error loading module: \(error)")
Logger.shared.log("Error loading module: \(error)", type: "Error")
self.isLoading = false
}
}
@ -243,7 +243,7 @@ struct MediaInfoView: View {
}
}
} catch {
Logger.shared.log("Error loading module: \(error)")
Logger.shared.log("Error loading module: \(error)", type: "Error")
self.isLoading = false
}
}

View file

@ -140,6 +140,7 @@ struct SearchView: View {
}
private func performSearch() {
Logger.shared.log("Searching for: \(searchText)", type: "General")
guard !searchText.isEmpty, let module = selectedModule else {
searchItems = []
hasNoResults = false
@ -168,7 +169,7 @@ struct SearchView: View {
}
}
} catch {
Logger.shared.log("Error loading module: \(error)")
Logger.shared.log("Error loading module: \(error)", type: "Error")
isSearching = false
hasNoResults = true
}

View file

@ -29,6 +29,9 @@ struct SettingsViewLogger: View {
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
HStack {
NavigationLink(destination: SettingsViewLoggerFilter(viewModel: filterViewModel)) {
Image(systemName: "gearshape")
Menu {
Button(action: {
UIPasteboard.general.string = logs
@ -46,8 +49,6 @@ struct SettingsViewLogger: View {
.resizable()
.frame(width: 20, height: 20)
}
NavigationLink(destination: SettingsViewLoggerFilter(viewModel: filterViewModel)) {
Image(systemName: "slider.horizontal.3")
}
}
}

View file

@ -26,7 +26,7 @@ class LogFilterViewModel: ObservableObject {
private let userDefaultsKey = "LogFilterStates"
private let hardcodedFilters: [(type: String, description: String, defaultState: Bool)] = [
("Global", "Logs for general events and activities.", true), // Turned on by default
("General", "Logs for general events and activities.", true), // Turned on by default
("Stream", "Logs for streaming and video playback.", true), // Turned on by default
("Error", "Logs for errors and critical issues.", true), // Turned on by default
("Debug", "Logs for debugging and troubleshooting.", false) // Turned off by default

View file

@ -28,12 +28,14 @@ struct SettingsView: View {
Section(header: Text("External Features")) {
NavigationLink(destination: SettingsViewModule()) {
Image(systemName: "puzzlepiece.fill")
Text("Modules")
}
}
Section(header: Text("Debug")) {
NavigationLink(destination: SettingsViewLogger()) {
Image(systemName: "doc.text.fill")
Text("Logs")
}
}