Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hotfix: better platform-agnostic handling of file:// urls #156

Merged
merged 6 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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