|
|
|
|
@ -34,7 +34,7 @@ impl FromStr for Status {
|
|
|
|
|
let code: i8 = splits.nth(1).unwrap().parse().unwrap(); |
|
|
|
|
let meta: String = String::from(splits.nth(2).unwrap()); |
|
|
|
|
|
|
|
|
|
Ok(Status { code, meta }) |
|
|
|
|
Ok(Status {code, meta}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -103,70 +103,77 @@ fn prompt_for_url(s: &mut Cursive) {
|
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn visit_url(s: &mut Cursive, url: &str) { |
|
|
|
|
fn visit_url(s: &mut Cursive, url_s: &str) { |
|
|
|
|
// Close URL popup if any
|
|
|
|
|
if s.find_id::<Dialog>("url_popup").is_some() { |
|
|
|
|
s.pop_layer(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
match get_data(&url) { |
|
|
|
|
Ok(new_content) => { |
|
|
|
|
let mut main_view = s.find_id::<SelectView>("main").unwrap(); |
|
|
|
|
let mut container = s.find_id::<Dialog>("container").unwrap(); |
|
|
|
|
|
|
|
|
|
container.set_title(url); |
|
|
|
|
main_view.clear(); |
|
|
|
|
main_view.add_all_str(new_content.lines()); |
|
|
|
|
main_view.set_on_submit(follow_link); |
|
|
|
|
} |
|
|
|
|
Err(msg) => { |
|
|
|
|
s.add_layer(Dialog::info(msg)); |
|
|
|
|
match parse_link(url_s) { |
|
|
|
|
Ok(url) => { |
|
|
|
|
match get_data(url) { |
|
|
|
|
Ok(new_content) => { |
|
|
|
|
let mut main_view = s.find_id::<SelectView>("main").unwrap(); |
|
|
|
|
let mut container = s.find_id::<Dialog>("container").unwrap(); |
|
|
|
|
|
|
|
|
|
container.set_title(url_s); |
|
|
|
|
main_view.clear(); |
|
|
|
|
main_view.add_all_str(new_content.lines()); |
|
|
|
|
main_view.set_on_submit(follow_link); |
|
|
|
|
} |
|
|
|
|
Err(msg) => { |
|
|
|
|
s.add_layer(Dialog::info(msg)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
Err(_) => { |
|
|
|
|
s.add_layer(Dialog::info(format!("Could not parse {}", url_s))); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn follow_link(s: &mut Cursive, line: &str) { |
|
|
|
|
let text = format!("{}", line); |
|
|
|
|
let re1 = Regex::new(r"^\[(.*)\|(URL:)?(.*)\]$").unwrap(); // `[Foo|URL:link]` links
|
|
|
|
|
let re2 = Regex::new(r"^=>\s(\S*)\s(\w*)$").unwrap(); // `=> link Foo` links
|
|
|
|
|
let link_regexp = Regex::new(r"^=>\s(\S*)(.*)?$").unwrap(); |
|
|
|
|
|
|
|
|
|
if re1.is_match(&text) { |
|
|
|
|
let caps = re1.captures(&text).unwrap(); |
|
|
|
|
let url = caps.get(3).map_or("", |m| m.as_str()); |
|
|
|
|
let next_url = parse_link(url); |
|
|
|
|
visit_url(s, &next_url) |
|
|
|
|
} else if re2.is_match(&text) { |
|
|
|
|
let caps = re2.captures(&text).unwrap(); |
|
|
|
|
if link_regexp.is_match(&text) { |
|
|
|
|
let caps = link_regexp.captures(&text).unwrap(); |
|
|
|
|
let url = caps.get(1).map_or("", |m| m.as_str()); |
|
|
|
|
let next_url = parse_link(url); |
|
|
|
|
visit_url(s, &next_url) |
|
|
|
|
visit_url(s, next_url.expect("Not an URL").as_str()) |
|
|
|
|
} else { |
|
|
|
|
() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn parse_link(url: &str) -> String { |
|
|
|
|
if url.starts_with("gemini://") { |
|
|
|
|
url.to_owned() |
|
|
|
|
} else if url.starts_with("/") { |
|
|
|
|
format!("gemini://{}{}", get_last_host(), url) |
|
|
|
|
} else { |
|
|
|
|
format!("gemini://{}/{}", get_last_host(), url) |
|
|
|
|
fn parse_link(url: &str) -> Result<url::Url, url::ParseError> { |
|
|
|
|
match get_last_host() { |
|
|
|
|
Some(host) => { |
|
|
|
|
let url_s = if url.starts_with("gemini://") { |
|
|
|
|
url.to_owned() |
|
|
|
|
} else if url.starts_with("/") { |
|
|
|
|
format!("gemini://{}{}", host, url) |
|
|
|
|
} else { |
|
|
|
|
format!("gemini://{}/{}", host, url) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Url::parse(&url_s) |
|
|
|
|
}, |
|
|
|
|
None => { |
|
|
|
|
let url_s = if url.starts_with("gemini://") { |
|
|
|
|
url.to_owned() |
|
|
|
|
} else { |
|
|
|
|
format!("gemini://{}", url) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Url::parse(&url_s) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn is_link(line: &str) -> bool { |
|
|
|
|
let text = format!("{}", line); |
|
|
|
|
let re1 = Regex::new(r"^\[(.*)\|(URL:)?(.*)\]$").unwrap(); // `[Foo|URL:link]` links
|
|
|
|
|
let re2 = Regex::new(r"^=>\s(\S*)\s(\w*)$").unwrap(); // `=> link Foo` links
|
|
|
|
|
|
|
|
|
|
re1.is_match(&text) || re2.is_match(&text) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn get_data(url: &str) -> Result<String, String> { |
|
|
|
|
let urlp = Url::parse(url).unwrap(); |
|
|
|
|
let host = urlp.host_str().unwrap(); |
|
|
|
|
let path = urlp.path(); |
|
|
|
|
fn get_data(url: url::Url) -> Result<String, String> { |
|
|
|
|
let host = url.host_str().unwrap(); |
|
|
|
|
let path = url.path(); |
|
|
|
|
let urlf = format!("{}:1965", host); |
|
|
|
|
|
|
|
|
|
let mut builder = TlsConnector::builder(); |
|
|
|
|
@ -182,7 +189,7 @@ fn get_data(url: &str) -> Result<String, String> {
|
|
|
|
|
|
|
|
|
|
match mstream { |
|
|
|
|
Ok(mut stream) => { |
|
|
|
|
append_history(url); |
|
|
|
|
append_history(url.as_str()); |
|
|
|
|
|
|
|
|
|
let url_with_path = format!("{}\r\n", path); |
|
|
|
|
stream.write_all(url_with_path.as_bytes()).unwrap(); |
|
|
|
|
@ -204,21 +211,26 @@ fn go_back(s: &mut Cursive) {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn get_last_host() -> String { |
|
|
|
|
fn get_last_host() -> Option<String> { |
|
|
|
|
let mut file = File::open("/tmp/asuka_history").expect("file not found"); |
|
|
|
|
let mut content = String::new(); |
|
|
|
|
file.read_to_string(&mut content) |
|
|
|
|
.expect("Unable to read file"); |
|
|
|
|
let url = content.lines().last().unwrap(); |
|
|
|
|
let urlp = Url::parse(url).unwrap(); |
|
|
|
|
urlp.host_str().unwrap().to_owned() |
|
|
|
|
let last_url = content.lines().last(); |
|
|
|
|
match last_url { |
|
|
|
|
Some(url) => { |
|
|
|
|
let urlp = Url::parse(url).expect("not an URL"); |
|
|
|
|
Some(urlp.host_str().unwrap().to_owned()) |
|
|
|
|
}, |
|
|
|
|
None => None |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn get_previous_url() -> Option<String> { |
|
|
|
|
let mut file = OpenOptions::new() |
|
|
|
|
.read(true) |
|
|
|
|
.open("/tmp/asuka_history") |
|
|
|
|
.unwrap(); |
|
|
|
|
.expect("file not found"); |
|
|
|
|
let mut content = String::new(); |
|
|
|
|
file.read_to_string(&mut content) |
|
|
|
|
.expect("Unable to read file"); |
|
|
|
|
@ -238,7 +250,7 @@ fn append_history(url: &str) {
|
|
|
|
|
.write(true) |
|
|
|
|
.append(true) |
|
|
|
|
.open("/tmp/asuka_history") |
|
|
|
|
.unwrap(); |
|
|
|
|
.expect("file not found"); |
|
|
|
|
|
|
|
|
|
let line = format!("{}\n", url); |
|
|
|
|
file.write_all(line.as_bytes()) |
|
|
|
|
|