This commit is contained in:
Alex Wied
2026-06-30 19:25:15 -04:00
parent 5cea8e8307
commit 2a6e9432d9
21 changed files with 1039 additions and 235 deletions
+55 -100
View File
@@ -1,7 +1,6 @@
use crate::rdf::ontology::{LabeledIri, Ontology};
use crate::rdf::term_helper::{TermHelper, TermHelperMut};
use crate::rdf::vocab::{gl, rda};
use gl_search::{Schema, SearchDocument, SearchIndex, NamedFieldDocument, OwnedValue, doc, IndexWriter};
use gl_search::{Schema, SearchDocument, SearchIndex, doc, IndexWriter};
use http::StatusCode;
use iced::alignment::Horizontal;
use iced::widget::button::Style;
@@ -9,7 +8,6 @@ use iced::widget::grid::Sizing;
use iced::widget::{button, center, column, combo_box, container, grid, mouse_area, opaque, pick_list, row, scrollable, space, stack, table, text, text_input, toggler};
use iced::window::Settings;
use iced::{Background, Color, Element, Length, Subscription, Task, color, window};
use iced::widget::text::Wrapping;
use ldp::middleware::BasicAuthMiddleware;
use ldp::model::{KeyedDataset, QuadKey};
use ldp::reqwest::{Client, Url};
@@ -19,10 +17,11 @@ use ldp::{RdfSource, RdfSourceUpdateResponse, ResourceRequestBuilder, Serializat
use oxigraph::io::RdfFormat;
use oxigraph::model::vocab::{rdf, rdfs};
use oxigraph::model::{BaseDirection, Dataset, NamedNode, Quad, Term, TermRef};
use tracing::{debug, error, info, info_span, span, Level};
use tracing::{debug_span, error, trace};
use crate::rdf::conversion;
use crate::widget::iri_input::iri_input;
#[derive(Debug, Clone)]
#[derive(Clone, Debug)]
pub(crate) enum Message {
None,
Traverse,
@@ -43,7 +42,7 @@ pub(crate) enum Message {
HoverRow(QuadKey),
UnhoverRow(QuadKey),
QueryUpdated(String),
SetSearchResults(Vec<NamedFieldDocument>),
SetSearchResults(Vec<SearchDocument>),
QueryTypeUpdated(NamedNode),
SearchResultClicked(NamedNode),
DatatypeUpdated(QuadKey, Option<String>),
@@ -76,7 +75,7 @@ struct SearchState {
action: SearchResultClickAction,
query: String,
type_: LabeledIri,
results: Vec<NamedFieldDocument>,
results: Vec<SearchDocument>,
}
pub(crate) struct Publisher {
@@ -97,32 +96,31 @@ pub(crate) struct Publisher {
impl Publisher {
pub(crate) fn new() -> (Self, Task<Message>) {
let ontology = info_span!("Ontology Creation").in_scope(|| {
let ontology = debug_span!("Ontology Creation").in_scope(|| {
Ontology::builder()
.with_path("/home/alex/.local/share/org.graphofliberty.desktop/ontology")
.build()
.expect("Failed to build ontology")
});
let index = info_span!("Ontology Indexing").in_scope(|| {
let mut index = SearchIndex::builder()
//.with_path("/home/alex/.local/share/org.graphofliberty.desktop/index")
.build()
.expect("Failed to build search index");
let index = SearchIndex::builder()
//.with_path("/home/alex/.local/share/org.graphofliberty.desktop/index")
.build()
.expect("Failed to build search index");
let writer = index.writer().expect("Failed to create search index writer");
let classes_to_index = [
rdf::PROPERTY,
rdfs::CLASS,
];
let classes_to_index = [
rdf::PROPERTY,
rdfs::CLASS,
];
debug_span!("Ontology Indexing").in_scope(|| {
let mut writer = index.writer().expect("Failed to build index writer");
for class in &classes_to_index {
let class = class.into_owned();
if let Some(id) = ontology.catalog_id(&class) {
index.remove_all_of_type(id).expect("Failed to remove documents from search index");
writer.remove_all_of_type(id).expect("Failed to remove documents from search index");
for individual in ontology.individuals(&class) {
let info = ontology.info(&individual);
let info = ontology.info(&individual, &conversion::english());
if info.label.is_some() || info.comment.is_some() {
let mut document = doc!(
Schema::type_field() => id,
@@ -137,13 +135,12 @@ impl Publisher {
document.add_text(Schema::field(&field.name), info.comment.unwrap_or_default());
}
writer.add_document(document).expect("Failed to add document to search index");
writer.add(document).expect("Failed to add document to search index");
}
}
}
}
index
writer.commit().expect("Failed to commit changes to search index");
});
let mut abbreviated_datatypes = ontology
@@ -187,7 +184,7 @@ impl Publisher {
pub(crate) fn update(&mut self, message: Message) -> Task<Message> {
let mut task = Task::none();
debug!(?message);
trace!(?message);
match message {
Message::Traverse => {
@@ -223,13 +220,14 @@ impl Publisher {
}
if let Some(writer) = &self.index_writer {
writer.add_document(document).expect("Unable to add document to search index");
writer.add(document).expect("Unable to add document to search index");
}
}
}
Message::CommitIndex => {
if let Some(writer) = &mut self.index_writer {
writer.commit().expect("Unable to commit updates to search index");
self.index_writer = None;
}
}
Message::WindowClosed(id) => {
@@ -368,15 +366,20 @@ impl Publisher {
SearchResultClickAction::URLInput => self.ontology.catalog_id(&search_state.type_.iri),
};
search_state.query = new_query.clone();
let index = self.index.clone();
task = Task::future(async move {
tokio::task::spawn_blocking(move || {
let result = index.query(catalog_id, new_query.as_str(), Schema::all_fields())
.expect("Error encountered while querying index");
Message::SetSearchResults(result)
}).await.unwrap()
let query = new_query.clone();
let search_task = tokio::task::spawn_blocking(move || {
index.query(catalog_id, query.as_str(), Schema::all_fields(), 25)
});
task = Task::future(async {
match search_task.await {
Ok(Ok(documents)) => Message::SetSearchResults(documents),
Ok(Err(err)) => Message::ShowError(err.to_string()),
Err(err) => Message::ShowError(err.to_string()),
}
});
search_state.query = new_query;
};
}
Message::SetSearchResults(results) => {
@@ -551,11 +554,11 @@ impl Publisher {
container(space()).width(BUTTON_WIDTH)
};
let property_label = "foo"; /*self
let property_label = self
.ontology
.info(triple.predicate.as_ref())
.and_then(|info| info.label.clone())
.unwrap_or(self.ontology.abbreviate(triple.predicate.as_ref()));*/
.info(&triple.predicate, &conversion::english())
.label
.unwrap_or(self.ontology.abbreviate(triple.predicate.as_ref()));
let property: Element<Message> = if state.read_only {
text(property_label).into()
@@ -572,14 +575,13 @@ impl Publisher {
let value_label = term.value_as_named_node().and_then(|node| {
self.ontology
.info(&node.into_owned())
.info(&node.into_owned(), &conversion::english())
.label
.map(|label| container(text(label)))
});
let value = term
.value_as_named_node()
//.map(|node| self.ontology.abbreviate(node))
.map(|node| node.as_str().to_string())
.unwrap_or(term.value().to_string());
@@ -591,7 +593,8 @@ impl Publisher {
})
.unwrap_or(Horizontal::Left);
let foo = iri_input(self.ontology.prefixes(), "Object", value.as_str())
let object_input = iri_input(self.ontology.prefixes(), "Object", value.as_str())
.align_x(value_alignment)
.on_input(move |value| Message::ValueUpdated(key, value))
.on_control_click(Message::OpenQueryWindow(SearchResultClickAction::Object(key)));
@@ -608,8 +611,7 @@ impl Publisher {
.on_input(move |input| {
let value = if input.is_empty() { None } else { Some(input) };
Message::DatatypeUpdated(key, value)
})
.into()
}).into()
};
let language_input = match term.datatype() {
@@ -647,9 +649,7 @@ impl Publisher {
button_area,
property,
value_label,
//value_input,
foo,
//search_launcher,
object_input,
datatype_selector,
language_input,
direction_slider,
@@ -668,7 +668,7 @@ impl Publisher {
let buttons = entities.map(|entity| {
let label = self
.ontology
.info(&entity)
.info(&entity, &conversion::english())
.label
.unwrap_or(entity.as_str().to_string());
button(text(label))
@@ -699,17 +699,15 @@ impl Publisher {
let mut columns = vec![];
for field in self.ontology.fields_for_class(&search_state.type_.iri) {
let header_text = field.label.as_ref().unwrap_or(&field.name);
columns.push(table::column(text(header_text), |document: &NamedFieldDocument| {
let cell_value = document.0
.get(&field.name)
/*columns.push(table::column(text(header_text), |document: &QueryResult| {
let cell_value = document.0.get(&field.name)
.and_then(|values| values.first())
.map(|value| match value {
OwnedValue::Str(string) => string,
_ => "???",
}).unwrap_or("");
let iri = document.0
.get("iri")
let iri = document.get("iri")
.and_then(|values| values.first())
.map(|value| match value {
OwnedValue::Str(string) => string,
@@ -719,50 +717,9 @@ impl Publisher {
button(text(cell_value).wrapping(Wrapping::Word))
.on_press(Message::SearchResultClicked(NamedNode::new_unchecked(iri)))
.style(button::text)
}).width(Length::Fixed(256.0)));
}).width(Length::Fixed(256.0)));*/
}
/*let label_column = table::column("Label", |result: &NamedNode| {
let header_text = self
.ontology
.info(result.as_ref())
.and_then(|info| info.label.clone())
.unwrap_or("".to_string());
button(text(header_text))
.on_press(Message::SearchResultClicked(result.clone()))
.style(button::text)
});
let type_column = table::column("Type", |result: &NamedNode| {
let header_text = self
.ontology
.info(result.as_ref())
.and_then(|info| self.ontology.info(info.type_.as_ref()))
.and_then(|info| info.label.clone())
.unwrap_or("Unknown".to_string());
button(text(header_text))
.on_press(Message::SearchResultClicked(result.clone()))
.style(button::text)
});
let description_column = table::column("Description", |result: &NamedNode| {
let header_text = self.ontology.info(result.as_ref())
.and_then(|info| info.comment.clone())
.unwrap_or("Unknown".to_string());
button(text(header_text))
.on_press(Message::SearchResultClicked(result.clone()))
.style(button::text)
});
let iri_column = table::column("IRI", |result: &NamedNode| {
button(text(result.as_str()))
.on_press(Message::SearchResultClicked(result.clone()))
.style(button::text)
});*/
let results_table = if columns.is_empty() {
None
} else {
@@ -779,9 +736,10 @@ impl Publisher {
let index_button = button("Index").on_press(Message::Traverse);
let search_launcher = button(text("\u{1f50e}"))
.on_press(Message::OpenQueryWindow(SearchResultClickAction::URLInput))
.style(button::text);
let address_input = iri_input(self.ontology.prefixes(), "URL", &self.url_input)
.on_input(Message::URLInputChanged)
.on_submit(Message::URLInputSubmitted)
.on_control_click(Message::OpenQueryWindow(SearchResultClickAction::URLInput));
let mut rows: Vec<Element<Message>> = vec![];
rows = self
@@ -812,10 +770,7 @@ impl Publisher {
row![
add_row_button,
index_button,
search_launcher,
text_input("URL", &self.url_input)
.on_input(Message::URLInputChanged)
.on_submit(Message::URLInputSubmitted),
address_input,
save_button,
],
scrollable(body),