Skip to content

Commit

Permalink
hotfix: better platform-agnostic handling of file:// urls (#156)
Browse files Browse the repository at this point in the history
  • Loading branch information
a5huynh authored Aug 9, 2022
1 parent ad3851b commit 6642454
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/client/src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use yew::prelude::*;

use btn::DeleteButton;
use shared::response::{LensResult, SearchResult};
use shared::url_to_file_path;
use url::Url;

#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -114,8 +115,7 @@ pub fn search_result_component(props: &SearchResultProps) -> Html {
.clone()
.unwrap_or_else(|| "example.com".to_string());

let path = url.path();

let path = url_to_file_path(url.path(), false);
let uri_icon = if url.scheme() == "file" {
html! {
<icons::DesktopComputerIcon
Expand Down
18 changes: 18 additions & 0 deletions crates/shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,21 @@ pub struct SettingOpts {
pub form_type: FormType,
pub help_text: Option<String>,
}

/// A platform-agnostic way to turn a URL file path into something that can
/// be opened & crawled.
pub fn url_to_file_path(path: &str, is_windows: bool) -> String {
// Unescape colons & spaces
let mut path = path.replace("%3A", ":").replace("%20", " ");
// Strip superfluous path prefix
if is_windows {
path = path
.strip_prefix('/')
.map(|s| s.to_string())
.unwrap_or(path);
// Convert path dividers into Windows specific ones.
path = path.replace('/', "\\");
}

path
}
27 changes: 23 additions & 4 deletions crates/spyglass/src/crawler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ use url::{Host, Url};
use entities::models::{crawl_queue, fetch_history};
use entities::sea_orm::prelude::*;
use entities::sea_orm::DatabaseConnection;

pub mod bootstrap;
pub mod robots;
use shared::url_to_file_path;

use crate::crawler::bootstrap::create_archive_url;
use crate::fetch::HTTPClient;
use crate::scraper::{html_to_text, DEFAULT_DESC_LENGTH};

pub mod bootstrap;
pub mod robots;
use robots::check_resource_rules;

// TODO: Make this configurable by domain
Expand Down Expand Up @@ -247,7 +248,25 @@ impl Crawler {
_: &crawl_queue::Model,
url: &Url,
) -> anyhow::Result<Option<CrawlResult>, anyhow::Error> {
let path = Path::new(url.path());
// Attempt to convert from the URL to a file path
#[allow(unused_assignments)]
let mut url_path = url
.to_file_path()
.map(|p| p.display().to_string())
.unwrap_or_else(|_| url.path().to_string());

#[cfg(not(target_os = "windows"))]
{
url_path = url_to_file_path(&url_path, false);
}

// Fixes issues handling Windows drive paths
#[cfg(target_os = "windows")]
{
url_path = url_to_file_path(&url.path(), true);
}

let path = Path::new(&url_path);
// Is this a file and does this exist?
if !path.exists() || !path.is_file() {
return Ok(None);
Expand Down
1 change: 1 addition & 0 deletions crates/spyglass/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::api::start_api_ipc;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config::new();

#[cfg(not(debug_assertions))]
let _guard = if config.user_settings.disable_telementry {
None
} else {
Expand Down
8 changes: 4 additions & 4 deletions crates/spyglass/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ pub async fn manager_task(
let cmd = Command::Fetch(CrawlTask { id: task.id });
if queue.send(cmd).await.is_err() {
eprintln!("unable to send command to worker");
return;
}
}
// ignore everything else
_ => {
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
_ => {}
}

// Wait a little before we dequeue another URL
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
}
}

Expand Down
10 changes: 9 additions & 1 deletion crates/tauri/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,15 @@ pub async fn open_result(_: tauri::Window, url: &str) -> Result<(), String> {
if let Ok(mut url) = url::Url::parse(url) {
// treat open files as a local action.
if url.scheme() == "file" {
let _ = url.set_host(Some("localhost"));
let _ = url.set_host(None);

#[cfg(target_os = "windows")]
{
use shared::url_to_file_path;
let path = url_to_file_path(url.path(), true);
open::that(format!("file://{}", path)).unwrap();
return Ok(());
}
}

open::that(url.to_string()).unwrap();
Expand Down
2 changes: 2 additions & 0 deletions crates/tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
#[allow(unused_imports)]
use std::borrow::Cow;
use std::io;
use std::path::PathBuf;
Expand Down Expand Up @@ -42,6 +43,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let ctx = tauri::generate_context!();
let config = Config::new();

#[cfg(not(debug_assertions))]
let _guard = if config.user_settings.disable_telementry {
None
} else {
Expand Down
3 changes: 2 additions & 1 deletion plugins/local-file-indexer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ path = "src/main.rs"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
spyglass-plugin = { path = "../../crates/spyglass-plugin" }
spyglass-plugin = { path = "../../crates/spyglass-plugin" }
url = "2.2.2"
7 changes: 6 additions & 1 deletion plugins/local-file-indexer/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use spyglass_plugin::*;
use std::collections::HashSet;
use std::path::Path;
use url::Url;

#[derive(Default)]
struct Plugin {
Expand All @@ -21,7 +22,11 @@ fn to_uri(path: &str) -> String {
"home.local".into()
};

format!("file://{}/{}", host, path)
let mut new_url = Url::parse("file://").expect("Base URI");
let _ = new_url.set_host(Some(&host));
// Fixes issues handling windows drive letters
new_url.set_path(&path.replace(':', "%3A"));
new_url.to_string()
}

impl Plugin {
Expand Down

0 comments on commit 6642454

Please sign in to comment.