mirror of
https://github.com/Ferrite-iOS/Ferrite.git
synced 2026-04-21 00:42:07 +00:00
Ferrite: Cleanup and refine backend
- Fix how abrupt search cancellations work - Add a no results prompt if no results are found - Clean up how scraping model results are returned on error - Allow a base URL and dynamic base URL to be provided together Signed-off-by: kingbri <bdashore3@gmail.com>
This commit is contained in:
parent
eb326f3354
commit
9cfb12cb14
4 changed files with 31 additions and 18 deletions
|
|
@ -159,12 +159,12 @@ class ScrapingViewModel: ObservableObject {
|
||||||
// RSS feed scraper
|
// RSS feed scraper
|
||||||
@MainActor
|
@MainActor
|
||||||
public func scrapeRss(source: Source, rss: String) -> [SearchResult] {
|
public func scrapeRss(source: Source, rss: String) -> [SearchResult] {
|
||||||
guard let rssParser = source.rssParser else {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
var tempResults: [SearchResult] = []
|
var tempResults: [SearchResult] = []
|
||||||
|
|
||||||
|
guard let rssParser = source.rssParser else {
|
||||||
|
return tempResults
|
||||||
|
}
|
||||||
|
|
||||||
var items = Elements()
|
var items = Elements()
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
@ -174,7 +174,7 @@ class ScrapingViewModel: ObservableObject {
|
||||||
toastModel?.toastDescription = "RSS scraping error, couldn't fetch items: \(error)"
|
toastModel?.toastDescription = "RSS scraping error, couldn't fetch items: \(error)"
|
||||||
print("RSS scraping error, couldn't fetch items: \(error)")
|
print("RSS scraping error, couldn't fetch items: \(error)")
|
||||||
|
|
||||||
return []
|
return tempResults
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in items {
|
for item in items {
|
||||||
|
|
@ -284,8 +284,10 @@ class ScrapingViewModel: ObservableObject {
|
||||||
// HTML scraper
|
// HTML scraper
|
||||||
@MainActor
|
@MainActor
|
||||||
public func scrapeHtml(source: Source, baseUrl: String, html: String) async -> [SearchResult] {
|
public func scrapeHtml(source: Source, baseUrl: String, html: String) async -> [SearchResult] {
|
||||||
|
var tempResults: [SearchResult] = []
|
||||||
|
|
||||||
guard let htmlParser = source.htmlParser else {
|
guard let htmlParser = source.htmlParser else {
|
||||||
return []
|
return tempResults
|
||||||
}
|
}
|
||||||
|
|
||||||
var rows = Elements()
|
var rows = Elements()
|
||||||
|
|
@ -297,11 +299,9 @@ class ScrapingViewModel: ObservableObject {
|
||||||
toastModel?.toastDescription = "Scraping error, couldn't fetch rows: \(error)"
|
toastModel?.toastDescription = "Scraping error, couldn't fetch rows: \(error)"
|
||||||
print("Scraping error, couldn't fetch rows: \(error)")
|
print("Scraping error, couldn't fetch rows: \(error)")
|
||||||
|
|
||||||
return []
|
return tempResults
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempResults: [SearchResult] = []
|
|
||||||
|
|
||||||
// If there's an error, continue instead of returning with nothing
|
// If there's an error, continue instead of returning with nothing
|
||||||
for row in rows {
|
for row in rows {
|
||||||
do {
|
do {
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ public class SourceManager: ObservableObject {
|
||||||
// If there's no base URL and it isn't dynamic, return before any transactions occur
|
// If there's no base URL and it isn't dynamic, return before any transactions occur
|
||||||
let dynamicBaseUrl = sourceJson.dynamicBaseUrl ?? false
|
let dynamicBaseUrl = sourceJson.dynamicBaseUrl ?? false
|
||||||
|
|
||||||
if (!dynamicBaseUrl && sourceJson.baseUrl == nil) || (dynamicBaseUrl && sourceJson.baseUrl != nil) {
|
if !dynamicBaseUrl, sourceJson.baseUrl == nil {
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
toastModel?.toastDescription = "Not adding this source because base URL parameters are malformed. Please contact the source dev."
|
toastModel?.toastDescription = "Not adding this source because base URL parameters are malformed. Please contact the source dev."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ struct ContentView: View {
|
||||||
|
|
||||||
await scrapingModel.scanSources(sources: sources.compactMap { $0 })
|
await scrapingModel.scanSources(sources: sources.compactMap { $0 })
|
||||||
|
|
||||||
if realDebridEnabled {
|
if realDebridEnabled, !scrapingModel.searchResults.isEmpty {
|
||||||
await debridManager.populateDebridHashes(scrapingModel.searchResults)
|
await debridManager.populateDebridHashes(scrapingModel.searchResults)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,24 +52,37 @@ struct SearchResultsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.overlay {
|
.overlay {
|
||||||
if scrapingModel.searchResults.isEmpty, navModel.showSearchProgress {
|
if scrapingModel.searchResults.isEmpty {
|
||||||
VStack(spacing: 5) {
|
if navModel.showSearchProgress {
|
||||||
ProgressView()
|
VStack(spacing: 5) {
|
||||||
Text("Loading \(scrapingModel.currentSourceName ?? "")")
|
ProgressView()
|
||||||
|
Text("Loading \(scrapingModel.currentSourceName ?? "")")
|
||||||
|
}
|
||||||
|
} else if isSearching, scrapingModel.runningSearchTask != nil {
|
||||||
|
Text("No results found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: navModel.selectedTab) { tab in
|
.onChange(of: navModel.selectedTab) { tab in
|
||||||
// Cancel the search if tab is switched
|
// Cancel the search if tab is switched while search is in progress
|
||||||
if tab != .search, isSearching, navModel.showSearchProgress {
|
if tab != .search, navModel.showSearchProgress {
|
||||||
scrapingModel.runningSearchTask?.cancel()
|
scrapingModel.runningSearchTask?.cancel()
|
||||||
|
scrapingModel.runningSearchTask = nil
|
||||||
dismissSearch()
|
dismissSearch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onChange(of: scrapingModel.searchResults) { _ in
|
||||||
|
// Cleans up any leftover search results in the event of an abrupt cancellation
|
||||||
|
if !isSearching {
|
||||||
|
scrapingModel.searchResults = []
|
||||||
|
}
|
||||||
|
}
|
||||||
.onChange(of: isSearching) { changed in
|
.onChange(of: isSearching) { changed in
|
||||||
// Clear the results array on cancel
|
// Clear the results array and cleans up search tasks on cancel
|
||||||
if !changed {
|
if !changed {
|
||||||
scrapingModel.searchResults = []
|
scrapingModel.searchResults = []
|
||||||
|
scrapingModel.runningSearchTask?.cancel()
|
||||||
|
scrapingModel.runningSearchTask = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue