This commit is contained in:
2026-08-05 18:33:30 -04:00
parent 7ce5ed118d
commit cd47d868c1
20 changed files with 307 additions and 181 deletions
+4 -4
View File
@@ -1,12 +1,11 @@
use crate::navigator::Navigator;
use crate::rdf::curie::CurieHelper;
use crate::rdf::ontology::{LabeledIri, Ontology};
use crate::rdf::term_helper::{TermHelper, TermHelperMut};
use crate::rdf::vocab::rda;
use crate::widget::iri_input::iri_input;
use crate::widget::navigation_area::navigation_area;
use gl_graph::vocab::rdac;
use gl_search::language;
use gl_search::{IndexWriter, Schema, SearchDocument, SearchIndex, Value};
use gl_search::{Schema, SearchDocument, SearchIndex, Value};
use http::StatusCode;
use iced::alignment::Horizontal;
use iced::keyboard::{Event, key};
@@ -25,6 +24,7 @@ use oxigraph::io::RdfFormat;
use oxigraph::model::vocab::{rdf, rdfs};
use oxigraph::model::{BaseDirection, Dataset, NamedNode, NamedOrBlankNode, Quad, Term};
use tracing::{debug_span, error, trace};
use gl_graph::{vocab, CurieHelper};
#[derive(Clone, Debug)]
pub(crate) enum Message {
@@ -816,7 +816,7 @@ impl Publisher {
.collect();
let body: Element<Message> = if self.show_new_document_buttons {
let subclasses = self.ontology.subclasses_of(&rda::ENTITY.into_owned());
let subclasses = Vec::new(); // TODO self.ontology.subclasses_of(vocab::rda::ENTITY.into_owned());
let labeled_subclasses = subclasses.iter().map(|iri| self.ontology.info(iri, &*language::ENGLISH_OR_UNTAGGED));
column![self.view_new_entity_buttons(labeled_subclasses)].into()
} else {
+11 -50
View File
@@ -7,26 +7,20 @@ mod navigator;
mod theme;
mod args;
use std::sync::{Arc, RwLock};
use std::thread;
use clap::Parser;
use color_eyre::eyre::eyre;
use iced::futures::StreamExt;
use iced::Task;
use ldp::middleware::BasicAuthMiddleware;
use ldp::reqwest::{Client, Url};
use ldp::reqwest_middleware::ClientBuilder;
use ldp::traverse::Traverse;
use oxigraph::model::Dataset;
use tracing::{debug, debug_span, error, field};
use crate::app::{Message, Publisher};
use crate::app::Publisher;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{EnvFilter, fmt};
use tracing_subscriber::fmt::format::FmtSpan;
use gl_search::{DocType, Document, Schema, SearchIndex};
use gl_search::{Document, Schema, SearchIndex};
use crate::args::{AppArgs, Command};
use crate::rdf::curie::CurieHelper;
use crate::rdf::ontology::Ontology;
fn main() -> color_eyre::Result<()> {
@@ -50,52 +44,25 @@ fn main() -> color_eyre::Result<()> {
let args = AppArgs::parse();
match args.command {
Some(Command::Search(args)) => {
for doc in index.query(args.discriminant, &args.query, Schema::all_fields(), 5)? {
for doc in index.query(args.discriminant, &args.query, Schema::all_fields(), 500000)? {
println!("{}", doc.to_json(Schema::schema()));
}
}
Some(Command::Reindex) => {
let curie_helper = CurieHelper::new(Ontology::prefixes().clone());
let writer = Arc::new(RwLock::new(index.writer()?));
let mut writer = index.writer()?;
debug_span!("Clear Index").in_scope(|| {
let mut writer = writer.write()?;
writer.delete_all_documents()?;
writer.commit()
})?;
let store = ontology.store();
let writer_clone = writer.clone();
let index_classes_thread = thread::spawn(move || {
let span = debug_span!("Index Classes", documents = field::Empty).entered();
let writer = writer_clone.read().unwrap();
let count = gl_search::rdf::index_triples(DocType::RdfsClass, store, &*gl_search::language::ENGLISH_OR_UNTAGGED, &*writer)?;
{
let span = debug_span!("Index Schema", documents = field::Empty).entered();
let store = ontology.store();
let count = gl_search::rdf::index_schema(store, &*gl_search::language::ENGLISH_OR_UNTAGGED, &writer)?;
span.record("documents", count);
Ok::<(), gl_search::SearchError>(())
});
let store = ontology.store();
let writer_clone = writer.clone();
let index_properties_thread = thread::spawn(move || {
let span = debug_span!("Index Properties", documents = field::Empty).entered();
let writer = writer_clone.read().unwrap();
let count = gl_search::rdf::index_triples(DocType::RdfProperty, store, &*gl_search::language::ENGLISH_OR_UNTAGGED, &writer)?;
span.record("documents", count);
Ok::<(), gl_search::SearchError>(())
});
let store = ontology.store();
let writer_clone = writer.clone();
let index_concepts_thread = thread::spawn(move || {
let span = debug_span!("Index Concepts", documents = field::Empty).entered();
let writer = writer_clone.read().unwrap();
let count = gl_search::rdf::index_triples(DocType::SkosConcept, store, &*gl_search::language::ENGLISH_OR_UNTAGGED, &writer)?;
span.record("documents", count);
Ok::<(), gl_search::SearchError>(())
});
}
let starting_url = Url::parse("http://fedora.quill.lan/rest/")?;
let writer_clone = writer.clone();
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.name("repository-traversal")
@@ -114,23 +81,17 @@ fn main() -> color_eyre::Result<()> {
while let Some(result) = traversal.next().await {
match result {
Ok(rdf_source) => {
let writer = writer_clone.read().unwrap();
documents += gl_search::rdf::index_entity(rdf_source.dataset(), &*gl_search::language::ENGLISH_OR_UNTAGGED, &writer)?;
}
Err(err) => error!(?err),
}
}
debug!(documents, "Repository Traversal");
Ok::<(), gl_search::SearchError>(())
Ok::<_, gl_search::SearchError>(writer)
});
index_classes_thread.join().unwrap()?;
index_properties_thread.join().unwrap()?;
index_concepts_thread.join().unwrap()?;
runtime.block_on(traversal_task)??;
let mut writer = runtime.block_on(traversal_task)??;
debug_span!("Commit").in_scope(|| {
let mut writer = writer.write()?;
writer.commit()
})?;
}
-39
View File
@@ -1,39 +0,0 @@
use std::collections::BTreeMap;
#[derive(Clone)]
pub struct CurieHelper {
prefixes: BTreeMap<String, String>,
}
impl CurieHelper {
pub fn new(prefixes: BTreeMap<String, String>) -> Self {
Self {
prefixes,
}
}
pub fn abbreviate(&self, base: Option<&str>, iri: &str) -> Option<String> {
if let Some(base) = base && let Some(local_name) = iri.strip_prefix(base) {
return Some(format!(":{local_name}"));
}
for (name, base) in &self.prefixes {
if let Some(local_name) = iri.strip_prefix(base) {
return Some(format!("{name}:{local_name}"));
}
}
None
}
pub fn expand(&self, base: Option<&str>, abbreviated_iri: &str) -> Option<String> {
let (prefix, name) = abbreviated_iri.split_once(':')?;
if prefix == "" && let Some(base) = base {
Some(format!("{base}{name}"))
} else {
self.prefixes
.get(prefix)
.map(|base| format!("{base}{name}"))
}
}
}
+2 -2
View File
@@ -1,9 +1,9 @@
use crate::error;
use gl_graph::vocab::owl;
use oxigraph::model::{Dataset, GraphName, NamedNodeRef, NamedOrBlankNode, NamedOrBlankNodeRef, Term};
use oxigraph::sparql::SparqlEvaluator;
use oxigraph::store::Store;
use tracing::{debug, debug_span};
use crate::error;
use crate::rdf::vocab::owl;
const INFERENCE_GRAPH: NamedNodeRef = NamedNodeRef::new_unchecked("https://graphofliberty.org/inference");
const RDF_SCHEMA: NamedNodeRef = NamedNodeRef::new_unchecked("http://www.w3.org/2000/01/rdf-schema#");
+1 -3
View File
@@ -1,6 +1,4 @@
pub(crate) mod ontology;
pub(crate) mod term_helper;
pub mod vocab;
pub(crate) mod materialize;
pub(crate) mod conversion;
pub(crate) mod curie;
pub(crate) mod conversion;
+1 -1
View File
@@ -1,6 +1,6 @@
use crate::error;
use crate::rdf::vocab::gl;
use crate::rdf::{conversion, materialize};
use gl_graph::vocab::gl;
use gl_search::language::LanguageCondition;
use iced::futures::TryFutureExt;
use oxigraph::model::vocab::{rdf, rdfs, xsd};
-38
View File
@@ -1,38 +0,0 @@
pub mod gl {
use oxigraph::model::NamedNodeRef;
pub const TEMPLATE: NamedNodeRef =
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/template");
pub const INDEXED_BY_FIELD: NamedNodeRef =
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/indexedByField");
pub const CATEGORY_ID: NamedNodeRef =
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/categoryId");
pub const SEARCHABLE_CLASS: NamedNodeRef =
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/SearchableClass");
pub const ENTITY: NamedNodeRef =
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/Entity");
pub const ASSOCIATED_PROPERTY: NamedNodeRef =
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/associatedProperty");
pub const READ_ONLY: NamedNodeRef =
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/readOnly");
}
pub mod owl {
use oxigraph::model::NamedNodeRef;
pub const SAME_AS: NamedNodeRef =
NamedNodeRef::new_unchecked("http://www.w3.org/2002/07/owl#sameAs");
}
pub mod rda {
use oxigraph::model::NamedNodeRef;
pub const ENTITY: NamedNodeRef =
NamedNodeRef::new_unchecked("http://rdaregistry.info/Elements/c/C10013");
}
+2 -2
View File
@@ -1,4 +1,4 @@
use iced::{alignment, keyboard, widget, Element, Event, Length, Rectangle, Size};
use iced::{keyboard, widget, Element, Event, Length, Rectangle, Size};
use iced::advanced::{mouse, text, Shell, renderer};
use iced::advanced::layout::{Limits, Node};
use iced::advanced::{Layout, Widget};
@@ -6,7 +6,7 @@ use iced::advanced::widget::{tree, Tree, Operation};
use iced::clipboard::Content;
use iced::mouse::{Cursor, Interaction};
use iced::widget::text_input::{Catalog, Status, Style, StyleFn};
use crate::rdf::curie::CurieHelper;
use gl_graph::CurieHelper;
pub struct State {
control: bool,