Switch from shelling out to w3m to using html2text

Still can't figure out how to go back to the results list from the web view.

Also, it would be useful to be able to visit links in the web view.
这个提交包含在:
2018-11-17 16:10:32 -05:00
父节点 69e54b1035
当前提交 1e3cbe2972
共有 3 个文件被更改,包括 1062 次插入376 次删除

1359
Cargo.lock 自动生成的

文件差异内容过多而无法显示 加载差异

查看文件

@@ -5,13 +5,12 @@ authors = ["Tyler Hallada <tyler@hallada.net>"]
[dependencies] [dependencies]
termion = "1.5.1" termion = "1.5.1"
tui = "0.2.0"
liner = "0.4.4" liner = "0.4.4"
reqwest = "0.8.4" reqwest = "0.9.4"
scraper = "0.4.0" scraper = "0.8.1"
chan = "0.1.20" html2text = "0.1.8"
[dependencies.cursive] [dependencies.cursive]
version = "0.7.5" version = "0.9.2"
default-features = false default-features = false
features = ["termion-backend"] features = ["termion-backend"]

查看文件

@@ -1,22 +1,26 @@
extern crate chan;
extern crate cursive; extern crate cursive;
extern crate reqwest; extern crate reqwest;
extern crate scraper; extern crate scraper;
extern crate termion; extern crate termion;
extern crate html2text;
use std::process::{Command, Stdio}; use std::collections::{HashMap};
use cursive::Cursive; use cursive::Cursive;
use cursive::align::HAlign; use cursive::align::HAlign;
use cursive::event::{EventResult, Key}; use cursive::event::{EventResult, Key};
use cursive::theme::{BaseColor, Color, Theme}; use cursive::theme::{BaseColor, Color, PaletteColor, Theme};
use cursive::traits::*; use cursive::traits::*;
use cursive::views::{Dialog, EditView, OnEventView, SelectView}; use cursive::views::{
Dialog, EditView, HideableView,OnEventView, ScrollView, SelectView, TextView
};
use reqwest::Client; use reqwest::{Client, Url};
use scraper::{Html, Selector}; use scraper::{Html, Selector};
use html2text::from_read;
struct SearchResult { struct SearchResult {
title: String, title: String,
domain: String, domain: String,
@@ -27,7 +31,7 @@ struct SearchResult {
const DDG_HTML_URL: &str = "https://duckduckgo.com"; const DDG_HTML_URL: &str = "https://duckduckgo.com";
fn main() { fn main() {
let mut siv = Cursive::new(); let mut siv = Cursive::default();
siv.add_active_screen(); siv.add_active_screen();
let theme = get_dark_theme(&siv); let theme = get_dark_theme(&siv);
@@ -89,6 +93,11 @@ fn search(s: &mut Cursive, query: &str) {
} }
s.pop_layer(); s.pop_layer();
add_result_list(s, query, results);
}
}
fn add_result_list(s: &mut Cursive, query: &str, results: Vec<SearchResult>) {
s.add_layer( s.add_layer(
Dialog::new() Dialog::new()
.title(query) .title(query)
@@ -96,9 +105,8 @@ fn search(s: &mut Cursive, query: &str) {
.content(build_list(results)) .content(build_list(results))
) )
} }
}
fn build_list(results: Vec<SearchResult>) -> OnEventView<SelectView> { fn build_list(results: Vec<SearchResult>) -> HideableView<OnEventView<SelectView>> {
let mut result_view = SelectView::new().h_align(HAlign::Left); let mut result_view = SelectView::new().h_align(HAlign::Left);
for (i, result) in results.into_iter().enumerate() { for (i, result) in results.into_iter().enumerate() {
@@ -123,7 +131,10 @@ fn build_list(results: Vec<SearchResult>) -> OnEventView<SelectView> {
result_view.set_on_submit(open_url); result_view.set_on_submit(open_url);
let result_view = OnEventView::new(result_view) let result_view = HideableView::new(OnEventView::new(result_view)
.on_event('q', |s| {
s.quit();
})
.on_pre_event_inner(Key::Up, |s| { .on_pre_event_inner(Key::Up, |s| {
let from_bottom = (s.len() - 1) - s.selected_id().unwrap(); let from_bottom = (s.len() - 1) - s.selected_id().unwrap();
if from_bottom < 3 { if from_bottom < 3 {
@@ -139,28 +150,35 @@ fn build_list(results: Vec<SearchResult>) -> OnEventView<SelectView> {
s.select_up(2); s.select_up(2);
} }
Some(EventResult::Consumed(None)) Some(EventResult::Consumed(None))
}); }));
result_view result_view
} }
fn open_url(_: &mut Cursive, url: &str) { fn open_url(s: &mut Cursive, url: &str) {
Command::new("w3m") let term_size = s.screen_size();
.args(&[url]) let actual_url = Url::parse(url).unwrap();
.stdin(Stdio::inherit()) let hash_query: HashMap<_, _> = actual_url.query_pairs().into_owned().collect();
.stdout(Stdio::inherit()) let result_url = hash_query.get("uddg");
.output().unwrap(); let client = Client::new();
let mut resp = client.get(result_url.unwrap().as_str()).send().unwrap();
let text = from_read(resp.text().unwrap().as_bytes(), term_size.x - 3);
s.pop_layer();
s.add_layer(OnEventView::new(ScrollView::new(TextView::new(text)))
.on_event('q', |s| {
s.quit();
}));
} }
fn get_dark_theme(siv: &Cursive) -> Theme { fn get_dark_theme(siv: &Cursive) -> Theme {
// We'll return the current theme with a small modification // We'll return the current theme with a small modification
let mut theme = siv.current_theme().clone(); let mut theme = siv.current_theme().clone();
theme.colors.background = Color::TerminalDefault; theme.palette[PaletteColor::Background] = Color::TerminalDefault;
theme.colors.view = Color::Dark(BaseColor::Black); theme.palette[PaletteColor::View] = Color::Dark(BaseColor::Black);
theme.colors.shadow = Color::Dark(BaseColor::Black); theme.palette[PaletteColor::Primary] = Color::Dark(BaseColor::White);
theme.colors.primary = Color::Dark(BaseColor::White); theme.palette[PaletteColor::Tertiary] = Color::Dark(BaseColor::Black);
theme.colors.tertiary = Color::Dark(BaseColor::Black);
theme.shadow = false;
theme theme
} }