Skip to content

Commit

Permalink
Merge pull request #37 from GeoffreyChen777/macOS-native-dev
Browse files Browse the repository at this point in the history
Advanced Search #30
  • Loading branch information
GeoffreyChen777 authored Mar 12, 2022
2 parents 815af7f + 723b53c commit bac5388
Show file tree
Hide file tree
Showing 12 changed files with 449 additions and 29 deletions.
8 changes: 8 additions & 0 deletions PaperLib.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
BEB7583227559A700086E360 /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEB7583127559A700086E360 /* SearchBar.swift */; };
BEB7583427559CF00086E360 /* Misc.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEB7583327559CF00086E360 /* Misc.swift */; };
BEE4DA2727DB64DA00482A08 /* SupComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEE4DA2627DB64DA00482A08 /* SupComponent.swift */; };
BEE4DA2927DBB09000482A08 /* CacheRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEE4DA2827DBB09000482A08 /* CacheRepository.swift */; };
BEE4DA2B27DBB64F00482A08 /* PaperEntityCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEE4DA2A27DBB64F00482A08 /* PaperEntityCache.swift */; };
BEEB7AA22762C93B00383CCA /* Updater.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEEB7AA12762C93B00383CCA /* Updater.swift */; };
BEF5586327BDA9EC00BB281B /* Exporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEF5586227BDA9EC00BB281B /* Exporter.swift */; };
BEFAB71427C1543900804026 /* Preference.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEFAB71327C1543900804026 /* Preference.swift */; };
Expand Down Expand Up @@ -123,6 +125,8 @@
BEB7583127559A700086E360 /* SearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = "<group>"; };
BEB7583327559CF00086E360 /* Misc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Misc.swift; sourceTree = "<group>"; };
BEE4DA2627DB64DA00482A08 /* SupComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupComponent.swift; sourceTree = "<group>"; };
BEE4DA2827DBB09000482A08 /* CacheRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheRepository.swift; sourceTree = "<group>"; };
BEE4DA2A27DBB64F00482A08 /* PaperEntityCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaperEntityCache.swift; sourceTree = "<group>"; };
BEEB7AA12762C93B00383CCA /* Updater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Updater.swift; sourceTree = "<group>"; };
BEEB7AA32762CB1300383CCA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
BEF5586227BDA9EC00BB281B /* Exporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exporter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -352,6 +356,7 @@
BE79C9BC275131A9008F3E97 /* DBRepository.swift */,
BE5BE4A427582B2300E6F832 /* WebRepository.swift */,
BE5BE4A627582C6A00E6F832 /* FileRepository.swift */,
BEE4DA2827DBB09000482A08 /* CacheRepository.swift */,
);
path = Repositories;
sourceTree = "<group>";
Expand All @@ -361,6 +366,7 @@
children = (
BE79C9C7275142D1008F3E97 /* PaperEntity.swift */,
BE79C9CE275154D5008F3E97 /* PaperCategorizer.swift */,
BEE4DA2A27DBB64F00482A08 /* PaperEntityCache.swift */,
);
path = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -510,6 +516,7 @@
BE5376C727C513CA005984AD /* GeneralPage.swift in Sources */,
BE79C9B427512F96008F3E97 /* DependencyInjector.swift in Sources */,
BE55162727C45E0D00DB92D8 /* Textfield.swift in Sources */,
BEE4DA2B27DBB64F00482A08 /* PaperEntityCache.swift in Sources */,
BE79C9B227512EEA008F3E97 /* SidebarView.swift in Sources */,
BE79C9BA275130F8008F3E97 /* EntitiesInteractor.swift in Sources */,
BE79C9BD275131A9008F3E97 /* DBRepository.swift in Sources */,
Expand All @@ -520,6 +527,7 @@
BE5376C127C47457005984AD /* Table.swift in Sources */,
BE79C9C8275142D1008F3E97 /* PaperEntity.swift in Sources */,
BE07383727BC61B90072F8CC /* DBLP.swift in Sources */,
BEE4DA2927DBB09000482A08 /* CacheRepository.swift in Sources */,
BE79C9D72752F9F4008F3E97 /* DetailSection.swift in Sources */,
BE79C99E27512D02008F3E97 /* ContentView.swift in Sources */,
BE79C9D32752DCFF008F3E97 /* DetailView.swift in Sources */,
Expand Down
Binary file not shown.
7 changes: 5 additions & 2 deletions PaperLib/AppEnvironment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@ extension AppEnvironment {
let dbRepository = RealDBRepository(sharedState: sharedState)
let fileRepository = RealFileDBRepository()
let webRepository = RealWebRepository()
let cacheRepository = RealCacheRepository(sharedState: sharedState)

return .init(dbRepository: dbRepository, fileRepository: fileRepository, webRepository: webRepository)
return .init(dbRepository: dbRepository, fileRepository: fileRepository, webRepository: webRepository, cacheRepository: cacheRepository)
}

private static func configuredInteractors(sharedState: SharedState, repositories: DIContainer.Repositories) -> DIContainer.Interactors {
let entitiesInteractor = RealEntitiesInteractor(
sharedState: sharedState,
dbRepository: repositories.dbRepository,
fileRepository: repositories.fileRepository,
webRepository: repositories.webRepository
webRepository: repositories.webRepository,
cacheRepository: repositories.cacheRepository
)

return .init(entitiesInteractor: entitiesInteractor)
Expand All @@ -47,5 +49,6 @@ extension DIContainer {
let dbRepository: DBRepository
let fileRepository: FileRepository
let webRepository: WebRepository
let cacheRepository: CacheRepository
}
}
2 changes: 2 additions & 0 deletions PaperLib/Injected/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ struct ViewState {

var processingQueueCount = StateWrapper(0)
var realmReinited = StateWrapper(nil as Date?)

var searchMode = StateWrapper(SearchMode.general)
}

struct SharedData {
Expand Down
63 changes: 60 additions & 3 deletions PaperLib/Interactors/EntitiesInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum InteractorError: Error {
case FileError(error: Error)
case WebError(error: Error)
case DBError(error: Error)
case CacheError(error: Error)
}

protocol EntitiesInteractor {
Expand Down Expand Up @@ -50,20 +51,22 @@ class RealEntitiesInteractor: EntitiesInteractor {
let dbRepository: DBRepository
let fileRepository: FileRepository
let webRepository: WebRepository
let cacheRepository: CacheRepository

let exporter: Exporter

let cancelBags: CancelBags = .init(["apiVersion", "timer", "entities", "categorizer-tags", "categorizer-folders", "entitiesByIds", "update", "add", "scrape", "delete", "edit", "folders-edit", "delete-categorizer", "open-lib", "plugin", "tag", "folder"])
let cancelBags: CancelBags = .init(["apiVersion", "timer", "entities", "categorizer-tags", "categorizer-folders", "entitiesByIds", "update", "add", "scrape", "delete", "edit", "folders-edit", "delete-categorizer", "open-lib", "plugin", "tag", "folder", "cache"])

var routineTimer: Publishers.Autoconnect<Timer.TimerPublisher> = Timer.publish(every: 86400, on: .main, in: .common).autoconnect()

init(sharedState: SharedState, dbRepository: DBRepository, fileRepository: FileRepository, webRepository: WebRepository) {
init(sharedState: SharedState, dbRepository: DBRepository, fileRepository: FileRepository, webRepository: WebRepository, cacheRepository: CacheRepository) {
self.logger = Logger()
self.sharedState = sharedState

self.dbRepository = dbRepository
self.fileRepository = fileRepository
self.webRepository = webRepository
self.cacheRepository = cacheRepository
self.exporter = Exporter()

self.setRoutineTimer()
Expand All @@ -88,6 +91,12 @@ class RealEntitiesInteractor: EntitiesInteractor {
return InteractorError.DBError(error: dbError)
}
}
.flatMap { entities in
self.cacheRepository.filter(entities: entities, query: search)
.mapError { cacheError in
return InteractorError.CacheError(error: cacheError)
}
}
.sinkToLoadable {
entities.wrappedValue.setIsLoading(cancelBag: self.cancelBags[cancelBagKey])
entities.wrappedValue = $0
Expand All @@ -111,6 +120,7 @@ class RealEntitiesInteractor: EntitiesInteractor {

func add(from urlList: [URL]) {
self.cancelBags.cancel(for: "add")
self.cancelBags.cancel(for: "cache")

// 1. Files processing and web scraping publishers.
var publisherList: [AnyPublisher<PaperEntityDraft, InteractorError>] = .init()
Expand Down Expand Up @@ -138,6 +148,9 @@ class RealEntitiesInteractor: EntitiesInteractor {
let c = publisherList.count

// 2. Database processing publishers.
var successedIds: [ObjectId] = .init()
let successedIdsPublisher: CurrentValueSubject<[ObjectId], InteractorError> = .init([])

Publishers.MergeMany(publisherList)
.collect()
.flatMap { entityDrafts in
Expand All @@ -162,6 +175,10 @@ class RealEntitiesInteractor: EntitiesInteractor {
for (entityDraft, success) in zip(entityDrafts, successes) where !success {
unsuccessedEntityList.append(entityDraft)
}
for (entityDraft, success) in zip(entityDrafts, successes) where success {
successedIds.append(entityDraft.id)
}

return Just<[PaperEntityDraft]>
.withErrorType(unsuccessedEntityList, InteractorError.self)
.eraseToAnyPublisher()
Expand All @@ -181,13 +198,47 @@ class RealEntitiesInteractor: EntitiesInteractor {
}
self.logger.error("Cannot add this paper: \(String(describing: error))")
}
case .finished: self.logger.info("Add successful.")
case .finished: do {
self.logger.info("Add successful.")
successedIdsPublisher.send(successedIds)
}
}
self.sharedState.viewState.processingQueueCount.value -= c
},
receiveValue: { _ in
})
.store(in: self.cancelBags["add"])

// 3. Create fulltext cache

// successedIdsPublisher
// .flatMap { ids in
// self.dbRepository.entities(ids: Set(ids), search: nil, publication: nil, flag: false, tags: [], folders: [], sort: "desc")
// .mapError { error in
// return InteractorError.DBError(error: error)
// }
// }
// .flatMap { entities in
// self.cacheRepository.add(entities: entities)
// .mapError { error in
// return InteractorError.CacheError(error: error)
// }
// }
// .sink(
// receiveCompletion: { completion in
// switch completion {
// case .failure(let error): do {
// self.logger.error("Cannot create fulltext cache: \(String(describing: error))")
// }
// case .finished: do {
// self.logger.info("Create fulltext cache successful.")
// }
// }
// },
// receiveValue: { _ in
// })
// .store(in: self.cancelBags["cache"])

}

// MARK: - Delete
Expand All @@ -198,6 +249,12 @@ class RealEntitiesInteractor: EntitiesInteractor {
Just<Void>
.withErrorType(InteractorError.self)
.flatMap {
self.cacheRepository.delete(ids: Array(ids))
.mapError { dbError in
return InteractorError.CacheError(error: dbError)
}
}
.flatMap { _ in
self.dbRepository.delete(ids: Array(ids))
.mapError { dbError in
return InteractorError.DBError(error: dbError)
Expand Down
20 changes: 20 additions & 0 deletions PaperLib/Models/PaperEntityCache.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// PaperEntityCache.swift
// PaperLib
//
// Created by GeoffreyChen on 11/03/2022.
//

import Foundation
import RealmSwift

class PaperEntityCache: Object, ObjectKeyIdentifiable {
@Persisted var fulltext: String = ""
@Persisted var id: ObjectId

convenience init(id: ObjectId, fulltext: String?) {
self.init()
self.id = id
self.fulltext = fulltext ?? ""
}
}
Loading

0 comments on commit bac5388

Please sign in to comment.