diff options
author | NerdyPepper <[email protected]> | 2018-07-30 17:18:06 +0100 |
---|---|---|
committer | NerdyPepper <[email protected]> | 2018-07-30 17:18:06 +0100 |
commit | cb93bc02b13432ccfe5e231ebde1edd033a2b388 (patch) | |
tree | 6ee27b54969bc63f10ea646ae36198f19a1ab5c6 | |
parent | ffacbf9aec3342519190755a913faa11438f3f28 (diff) | |
parent | 82077440d0ee3e6f64921461e45bb8be764ec57d (diff) |
Merge branch 'master' of https://github.com/nerdypepper/taizen
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/content.rs | 59 | ||||
-rw-r--r-- | src/main.rs | 123 |
3 files changed, 91 insertions, 92 deletions
@@ -2,6 +2,7 @@ | |||
2 | name = "taizen" | 2 | name = "taizen" |
3 | version = "0.1.0" | 3 | version = "0.1.0" |
4 | authors = ["NerdyPepper <[email protected]>"] | 4 | authors = ["NerdyPepper <[email protected]>"] |
5 | description = "TUI MediaWiki browser" | ||
5 | 6 | ||
6 | [dependencies] | 7 | [dependencies] |
7 | reqwest = { git = "https://github.com/seanmonstar/reqwest" } | 8 | reqwest = { git = "https://github.com/seanmonstar/reqwest" } |
diff --git a/src/content.rs b/src/content.rs index aa45207..8b48411 100644 --- a/src/content.rs +++ b/src/content.rs | |||
@@ -1,15 +1,15 @@ | |||
1 | extern crate reqwest; | ||
2 | extern crate serde_json; | ||
3 | extern crate cursive; | 1 | extern crate cursive; |
4 | extern crate regex; | 2 | extern crate regex; |
3 | extern crate reqwest; | ||
4 | extern crate serde_json; | ||
5 | extern crate urlencoding; | 5 | extern crate urlencoding; |
6 | 6 | ||
7 | use self::regex::Regex; | ||
7 | use cursive::theme::Effect; | 8 | use cursive::theme::Effect; |
8 | use cursive::utils::markup::StyledString; | 9 | use cursive::utils::markup::StyledString; |
9 | use cursive::Cursive; | ||
10 | use cursive::views::Dialog; | 10 | use cursive::views::Dialog; |
11 | use cursive::Cursive; | ||
11 | use serde_json::Value; | 12 | use serde_json::Value; |
12 | use self::regex::Regex; | ||
13 | use CONFIGURATION; | 13 | use CONFIGURATION; |
14 | 14 | ||
15 | pub fn query_url_gen(title: &str) -> String { | 15 | pub fn query_url_gen(title: &str) -> String { |
@@ -57,36 +57,33 @@ pub fn get_extract(v: &Value) -> Result<String, reqwest::Error> { | |||
57 | Ok(format!("{}", extract)) | 57 | Ok(format!("{}", extract)) |
58 | } | 58 | } |
59 | // ignore non strings | 59 | // ignore non strings |
60 | _ => Ok(format!("This page does not exist anymore")) | 60 | _ => Ok(format!("This page does not exist anymore")), |
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | pub fn extract_formatter(extract: String) -> StyledString { | 64 | pub fn extract_formatter(extract: String) -> StyledString { |
65 | let mut formatted = StyledString::new(); | 65 | let mut formatted = StyledString::new(); |
66 | 66 | ||
67 | let heading= Regex::new(r"^== (?P<d>.*) ==$").unwrap(); | 67 | let heading = Regex::new(r"^== (?P<d>.*) ==$").unwrap(); |
68 | let subheading= Regex::new(r"^=== (?P<d>.*) ===$").unwrap(); | 68 | let subheading = Regex::new(r"^=== (?P<d>.*) ===$").unwrap(); |
69 | let subsubheading= Regex::new(r"^==== (?P<d>.*) ====$").unwrap(); | 69 | let subsubheading = Regex::new(r"^==== (?P<d>.*) ====$").unwrap(); |
70 | 70 | ||
71 | for line in extract.lines() { | 71 | for line in extract.lines() { |
72 | if heading.is_match(line) { | 72 | if heading.is_match(line) { |
73 | formatted.append( | 73 | formatted.append(StyledString::styled( |
74 | StyledString::styled( | 74 | heading.replace(line, "$d"), |
75 | heading.replace(line, "$d"), Effect::Bold | 75 | Effect::Bold, |
76 | ) | 76 | )); |
77 | ); | ||
78 | } else if subheading.is_match(line) { | 77 | } else if subheading.is_match(line) { |
79 | formatted.append( | 78 | formatted.append(StyledString::styled( |
80 | StyledString::styled( | 79 | subheading.replace(line, "$d"), |
81 | subheading.replace(line, "$d"), Effect::Italic | 80 | Effect::Italic, |
82 | ) | 81 | )); |
83 | ); | ||
84 | } else if subsubheading.is_match(line) { | 82 | } else if subsubheading.is_match(line) { |
85 | formatted.append( | 83 | formatted.append(StyledString::styled( |
86 | StyledString::styled( | 84 | subsubheading.replace(line, "$d"), |
87 | subsubheading.replace(line, "$d"), Effect::Underline | 85 | Effect::Underline, |
88 | ) | 86 | )); |
89 | ); | ||
90 | } else { | 87 | } else { |
91 | formatted.append(StyledString::plain(line)); | 88 | formatted.append(StyledString::plain(line)); |
92 | } | 89 | } |
@@ -100,10 +97,9 @@ pub fn extract_formatter(extract: String) -> StyledString { | |||
100 | pub fn get_search_results(search: &str) -> Result<Vec<String>, reqwest::Error> { | 97 | pub fn get_search_results(search: &str) -> Result<Vec<String>, reqwest::Error> { |
101 | let url = search_url_gen(search); | 98 | let url = search_url_gen(search); |
102 | let mut res = reqwest::get(&url[..])?; | 99 | let mut res = reqwest::get(&url[..])?; |
103 | let v: Value = serde_json::from_str(&res.text()?) | 100 | let v: Value = serde_json::from_str(&res.text()?).unwrap_or_else(|e| { |
104 | .unwrap_or_else( |e| { | 101 | panic!("Recieved error {:?}", e); |
105 | panic!("Recieved error {:?}", e); | 102 | }); |
106 | } ); | ||
107 | 103 | ||
108 | let mut results: Vec<String> = vec![]; | 104 | let mut results: Vec<String> = vec![]; |
109 | for item in v[1].as_array().unwrap() { | 105 | for item in v[1].as_array().unwrap() { |
@@ -129,19 +125,18 @@ pub fn get_links(v: &Value) -> Result<Vec<String>, reqwest::Error> { | |||
129 | for item in arr { | 125 | for item in arr { |
130 | match item["title"] { | 126 | match item["title"] { |
131 | Value::String(ref title) => links.push(title.to_string()), | 127 | Value::String(ref title) => links.push(title.to_string()), |
132 | _ => links.push(String::from("lol")) | 128 | _ => links.push(String::from("lol")), |
133 | } | 129 | } |
134 | } | 130 | } |
135 | }, | 131 | } |
136 | _ => links.push(String::from("lol")) | 132 | _ => links.push(String::from("lol")), |
137 | }; | 133 | }; |
138 | 134 | ||
139 | Ok(links) | 135 | Ok(links) |
140 | } | 136 | } |
141 | 137 | ||
142 | pub fn pop_error(s: &mut Cursive, msg: String) { | 138 | pub fn pop_error(s: &mut Cursive, msg: String) { |
143 | s.add_layer(Dialog::text(format!("{}", msg)) | 139 | s.add_layer(Dialog::text(format!("{}", msg)).button("Ok", |s| s.quit())); |
144 | .button("Ok", |s| s.quit())); | ||
145 | } | 140 | } |
146 | 141 | ||
147 | pub fn handler(e: reqwest::Error) -> String { | 142 | pub fn handler(e: reqwest::Error) -> String { |
diff --git a/src/main.rs b/src/main.rs index ab35f2d..fd01af8 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,21 +1,19 @@ | |||
1 | extern crate clap; | ||
2 | extern crate cursive; | ||
1 | extern crate reqwest; | 3 | extern crate reqwest; |
2 | extern crate serde_json; | 4 | extern crate serde_json; |
3 | extern crate cursive; | ||
4 | extern crate clap; | ||
5 | #[macro_use] | 5 | #[macro_use] |
6 | extern crate lazy_static; | 6 | extern crate lazy_static; |
7 | 7 | ||
8 | use cursive::Cursive; | ||
9 | use cursive::traits::*; | 8 | use cursive::traits::*; |
10 | use cursive::views::{ | 9 | use cursive::views::{ |
11 | TextView, Dialog, EditView, | 10 | Dialog, DummyView, EditView, LinearLayout, OnEventView, SelectView, TextView, |
12 | SelectView, OnEventView, LinearLayout, | ||
13 | DummyView | ||
14 | }; | 11 | }; |
12 | use cursive::Cursive; | ||
15 | 13 | ||
16 | use serde_json::Value; | 14 | use serde_json::Value; |
17 | 15 | ||
18 | use clap::{Arg, App}; | 16 | use clap::{App, Arg}; |
19 | 17 | ||
20 | pub mod content; | 18 | pub mod content; |
21 | use content::*; | 19 | use content::*; |
@@ -24,7 +22,7 @@ pub mod theme; | |||
24 | use theme::*; | 22 | use theme::*; |
25 | 23 | ||
26 | struct Configuration { | 24 | struct Configuration { |
27 | wiki_url: String | 25 | wiki_url: String, |
28 | } | 26 | } |
29 | 27 | ||
30 | lazy_static! { | 28 | lazy_static! { |
@@ -33,14 +31,13 @@ lazy_static! { | |||
33 | 31 | ||
34 | fn main() { | 32 | fn main() { |
35 | parse_arguments(); | 33 | parse_arguments(); |
36 | 34 | ||
37 | // Initial setup | 35 | // Initial setup |
38 | let mut main = Cursive::default(); | 36 | let mut main = Cursive::default(); |
39 | 37 | ||
40 | // Set theme | 38 | // Set theme |
41 | main.set_theme(theme_gen()); | 39 | main.set_theme(theme_gen()); |
42 | 40 | ||
43 | |||
44 | main.add_global_callback('q', |s| s.quit()); | 41 | main.add_global_callback('q', |s| s.quit()); |
45 | main.add_global_callback('s', |s| search(s)); | 42 | main.add_global_callback('s', |s| search(s)); |
46 | 43 | ||
@@ -48,19 +45,23 @@ fn main() { | |||
48 | } | 45 | } |
49 | 46 | ||
50 | fn parse_arguments() -> Configuration { | 47 | fn parse_arguments() -> Configuration { |
51 | let matches = App::new("Taizen") | 48 | let matches = App::new(env!("CARGO_PKG_NAME")) |
52 | .version("0.1.0") | 49 | .version(env!("CARGO_PKG_VERSION")) |
53 | .author("NerdyPepper") | 50 | .author(env!("CARGO_PKG_AUTHORS")) |
54 | .about("TUI MediaWiki browser") | 51 | .about(env!("CARGO_PKG_DESCRIPTION")) |
55 | .arg(Arg::with_name("URL") | 52 | .arg( |
56 | .help("The URL of the wiki to be viewed") | 53 | Arg::with_name("URL") |
57 | .index(1)) | 54 | .help("The URL of the wiki to be viewed") |
58 | .arg(Arg::with_name("lang") | 55 | .index(1), |
59 | .short("l") | 56 | ) |
60 | .long("lang") | 57 | .arg( |
61 | .value_name("CODE") | 58 | Arg::with_name("lang") |
62 | .help("Choose the language for Wikipedia") | 59 | .short("l") |
63 | .takes_value(true)) | 60 | .long("lang") |
61 | .value_name("CODE") | ||
62 | .help("Choose the language for Wikipedia") | ||
63 | .takes_value(true), | ||
64 | ) | ||
64 | .get_matches(); | 65 | .get_matches(); |
65 | 66 | ||
66 | if matches.is_present("HELP") { | 67 | if matches.is_present("HELP") { |
@@ -68,50 +69,52 @@ fn parse_arguments() -> Configuration { | |||
68 | } | 69 | } |
69 | 70 | ||
70 | let lang = matches.value_of("lang").unwrap_or("en").to_string(); | 71 | let lang = matches.value_of("lang").unwrap_or("en").to_string(); |
71 | let wiki_url = matches.value_of("URL").unwrap_or(&format!("https://{}.wikipedia.org", lang)).to_string(); | 72 | let wiki_url = matches |
73 | .value_of("URL") | ||
74 | .unwrap_or(&format!("https://{}.wikipedia.org", lang)) | ||
75 | .to_string(); | ||
72 | 76 | ||
73 | Configuration { | 77 | Configuration { wiki_url } |
74 | wiki_url | ||
75 | } | ||
76 | } | 78 | } |
77 | 79 | ||
78 | fn search(s: &mut Cursive) { | 80 | fn search(s: &mut Cursive) { |
79 | |||
80 | fn go(s: &mut Cursive, search: &str) { | 81 | fn go(s: &mut Cursive, search: &str) { |
81 | s.pop_layer(); | 82 | s.pop_layer(); |
82 | let mut result = vec![]; | 83 | let mut result = vec![]; |
83 | match get_search_results(&search) { | 84 | match get_search_results(&search) { |
84 | Ok(x) => result = x, | 85 | Ok(x) => result = x, |
85 | Err(e) => pop_error(s,handler(e)), | 86 | Err(e) => pop_error(s, handler(e)), |
86 | }; | 87 | }; |
87 | let choose_result = SelectView::<String>::new() | 88 | let choose_result = SelectView::<String>::new() |
88 | .with_all_str(result) | 89 | .with_all_str(result) |
89 | .on_submit(|s, name|{ | 90 | .on_submit(|s, name| { |
90 | s.pop_layer(); | 91 | s.pop_layer(); |
91 | on_submit(s, name); | 92 | on_submit(s, name); |
92 | }) | 93 | }) |
93 | .scrollable(); | 94 | .scrollable(); |
94 | s.add_layer(Dialog::around(choose_result) | 95 | s.add_layer( |
95 | .title("Search Results") | 96 | Dialog::around(choose_result) |
96 | .button("Cancel", |s| match s.pop_layer() { _ => () }) | 97 | .title("Search Results") |
97 | .fixed_size(( 45,10 ))); | 98 | .button("Cancel", |s| match s.pop_layer() { |
99 | _ => (), | ||
100 | }) | ||
101 | .fixed_size((45, 10)), | ||
102 | ); | ||
98 | } | 103 | } |
99 | 104 | ||
100 | s.add_layer(Dialog::around(EditView::new() | 105 | s.add_layer( |
101 | .on_submit(go) | 106 | Dialog::around(EditView::new().on_submit(go).with_id("search")) |
102 | .with_id("search") | 107 | .title("Search for a page") |
103 | ) | 108 | .button("Go", |s| { |
104 | .title("Search for a page") | 109 | let search_txt = s.call_on_id("search", |v: &mut EditView| v.get_content()) |
105 | .button("Go", |s| { | 110 | .unwrap(); |
106 | let search_txt = s.call_on_id( "search", |v: &mut EditView| { | 111 | go(s, &search_txt); |
107 | v.get_content() | 112 | }) |
108 | }).unwrap(); | 113 | .button("Cancel", |s| match s.pop_layer() { |
109 | go(s, &search_txt); | 114 | _ => (), |
110 | }) | 115 | }) |
111 | .button("Cancel", |s| match s.pop_layer(){ | 116 | .fixed_size((35, 5)), |
112 | _ => () | 117 | ); |
113 | }) | ||
114 | .fixed_size(( 35, 5 ))); | ||
115 | } | 118 | } |
116 | 119 | ||
117 | fn on_submit(s: &mut Cursive, name: &str) { | 120 | fn on_submit(s: &mut Cursive, name: &str) { |
@@ -129,11 +132,11 @@ fn on_submit(s: &mut Cursive, name: &str) { | |||
129 | 132 | ||
130 | match get_extract(&v) { | 133 | match get_extract(&v) { |
131 | Ok(x) => extract = x, | 134 | Ok(x) => extract = x, |
132 | Err(e) => pop_error(s, handler(e)) | 135 | Err(e) => pop_error(s, handler(e)), |
133 | }; | 136 | }; |
134 | match get_links(&v) { | 137 | match get_links(&v) { |
135 | Ok(x) => link_vec = x, | 138 | Ok(x) => link_vec = x, |
136 | Err(e) => pop_error(s, handler(e)) | 139 | Err(e) => pop_error(s, handler(e)), |
137 | }; | 140 | }; |
138 | 141 | ||
139 | // get the act together | 142 | // get the act together |
@@ -149,12 +152,12 @@ fn on_submit(s: &mut Cursive, name: &str) { | |||
149 | Dialog::around( | 152 | Dialog::around( |
150 | OnEventView::new( | 153 | OnEventView::new( |
151 | LinearLayout::horizontal() | 154 | LinearLayout::horizontal() |
152 | .child(article_content.fixed_width(72)) | 155 | .child(article_content.fixed_width(72)) |
153 | .child(DummyView) | 156 | .child(DummyView) |
154 | .child(links) | 157 | .child(links), |
155 | ) | 158 | ).on_event('t', |s| match s.pop_layer() { |
156 | .on_event('t', |s| match s.pop_layer() { _ => () }) | 159 | _ => (), |
157 | ) | 160 | }), |
158 | .title(heading) | 161 | ).title(heading), |
159 | ); | 162 | ); |
160 | } | 163 | } |