Skip to content

Commit

Permalink
replace static regex condition with resolvable hostname detection, ad…
Browse files Browse the repository at this point in the history
…d gemini/to_gemini api
  • Loading branch information
yggverse committed Dec 12, 2024
1 parent 9411208 commit 325d550
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 35 deletions.
39 changes: 5 additions & 34 deletions src/app/browser/window/tab/item/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ use gtk::{
gdk::Texture,
gdk_pixbuf::Pixbuf,
gio::SocketClientEvent,
glib::{
gformat, GString, Priority, Regex, RegexCompileFlags, RegexMatchFlags, Uri, UriFlags,
UriHideFlags,
},
glib::{gformat, GString, Priority, Uri, UriFlags, UriHideFlags},
prelude::{EditableExt, FileExt, SocketClientExt, WidgetExt},
};
use sqlite::Transaction;
Expand Down Expand Up @@ -225,41 +222,15 @@ impl Page {
}
}
Request::Search(ref query) => {
// Try interpret URI manually
if Regex::match_simple(
r"^[^\/\s]+\.[\w]{2,}",
query,
RegexCompileFlags::DEFAULT,
RegexMatchFlags::DEFAULT,
) {
// Seems request contain some host, try append default scheme
// * make sure new request conversable to valid URI
match Uri::parse(&format!("gemini://{query}"), UriFlags::NONE) {
Ok(uri) => {
// Update navigation entry
self.navigation
.request
.widget
.entry
.set_text(&uri.to_string());

// Load page (without history record)
self.load(false);
}
Err(_) => {
// @TODO any action here?
}
}
} else {
// Plain text given, make search request to default provider
// try autocomplete scheme prefix @TODO optional resolve timeout
if self.navigation.request.to_gemini(500).is_none() {
// make search request to default provider @TODO optional
self.navigation.request.widget.entry.set_text(&format!(
"gemini://tlgs.one/search?{}",
Uri::escape_string(query, None, false)
));

// Load page (without history record)
self.load(false);
}
self.load(true)
}
};
}
Expand Down
40 changes: 39 additions & 1 deletion src/app/browser/window/tab/item/page/navigation/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use widget::Widget;

use crate::app::browser::{window::tab::item::Action as TabAction, Action as BrowserAction};
use gtk::{
gio::{Cancellable, NetworkAddress, Resolver},
glib::{gformat, GString, Uri, UriFlags},
prelude::EditableExt,
prelude::{EditableExt, NetworkAddressExt, ResolverExt},
};
use sqlite::Transaction;
use std::rc::Rc;
Expand Down Expand Up @@ -98,6 +99,13 @@ impl Request {
self.widget.entry.set_text(&self.source());
}

pub fn to_gemini(&self, resolver_timeout: u32) -> Option<GString> {
self.gemini(resolver_timeout).and_then(|url| {
self.widget.entry.set_text(&url);
Some(url)
})
}

// Getters

pub fn uri(&self) -> Option<Uri> {
Expand All @@ -118,6 +126,14 @@ impl Request {
text = postfix.into()
};

if let Some(postfix) = text.strip_prefix("file://") {
text = postfix.into()
};

if let Some(postfix) = text.strip_prefix("gemini://") {
text = postfix.into()
};

text
}

Expand All @@ -128,6 +144,28 @@ impl Request {
pub fn source(&self) -> GString {
gformat!("source:{}", self.strip_prefix())
}

pub fn gemini(&self, resolver_timeout: u32) -> Option<GString> {
// suggest scheme
let url = gformat!("gemini://{}", self.strip_prefix().trim());

// setup default resolver
// * wanted to detect value contain **resolvable** hostname
let resolver = Resolver::default();
resolver.set_timeout(resolver_timeout);

// is connectable
if let Ok(connectable) = NetworkAddress::parse_uri(&url, 1965) {
// is resolvable @TODO async
if resolver
.lookup_by_name(&connectable.hostname(), Cancellable::NONE)
.is_ok()
{
return Some(url);
}
}
None
}
}

// Tools
Expand Down

0 comments on commit 325d550

Please sign in to comment.