aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: ff87931de7c78de779c048850148dbabe8784882 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
extern crate reqwest;
extern crate serde_json;
extern crate cursive;
extern crate clap;
#[macro_use]
extern crate lazy_static;

use cursive::Cursive;
use cursive::traits::*;
use cursive::views::{ 
    TextView, Dialog, EditView,
    SelectView, OnEventView, LinearLayout,
    DummyView
};

use serde_json::Value;

use clap::{Arg, App};

pub mod content;
use content::*;

pub mod theme;
use theme::*;

struct Configuration {
    wiki_url: String
}

lazy_static! {
    static ref CONFIGURATION: Configuration = parse_arguments();
}

fn main() {
    parse_arguments();
    
    // Initial setup
    let mut main = Cursive::default();

    // Set theme
    main.set_theme(theme_gen());


    main.add_global_callback('q', |s| s.quit());
    main.add_global_callback('s', |s| search(s));

    main.run();
}

fn parse_arguments() -> Configuration {
    let matches = App::new("Taizen")
        .version("0.1.0")
        .author("NerdyPepper")
        .about("TUI MediaWiki browser")
        .arg(Arg::with_name("URL")
             .help("The URL of the wiki to be viewed")
             .index(1))
        .arg(Arg::with_name("lang")
             .short("l")
             .long("lang")
             .value_name("CODE")
             .help("Choose the language for Wikipedia")
             .takes_value(true))
        .get_matches();

    if matches.is_present("HELP") {
        std::process::exit(0);
    }
                               
    let lang = matches.value_of("lang").unwrap_or("en").to_string();
    let wiki_url = matches.value_of("URL").unwrap_or(&format!("https://{}.wikipedia.org", lang)).to_string();
    
    Configuration {
        wiki_url
    }
}

fn search(s: &mut Cursive) {

    fn go(s: &mut Cursive, search: &str) {
        s.pop_layer();
        let mut result = vec![];
        match get_search_results(&search) {
            Ok(x) => result = x,
            Err(e) => pop_error(s,handler(e)),
        };
        let choose_result = SelectView::<String>::new()
            .with_all_str(result)
            .on_submit(|s, name|{
                s.pop_layer();
                on_submit(s, name);
            });
        s.add_layer(Dialog::around(choose_result)
            .title("Search Results")
            .button("Cancel", |s| match s.pop_layer() { _ => () })
            .fixed_size(( 45,10 )));
    }

    s.add_layer(Dialog::around(EditView::new()
                               .on_submit(go)
                               .with_id("search")
                               )
                .title("Search for a page")
                .button("Go", |s| {
                    let search_txt = s.call_on_id( "search", |v: &mut EditView| {
                        v.get_content()
                    }).unwrap();
                    go(s, &search_txt);
                })
                .button("Cancel", |s| match s.pop_layer(){
                    _ => ()
                })
                .fixed_size(( 35, 5 )));
}

fn on_submit(s: &mut Cursive, name: &str) {
    // get article data
    let heading: String = name.to_string();
    let url = query_url_gen(&name.replace(" ", "_"));
    let mut extract = String::new();
    let mut link_vec: Vec<String> = vec![];

    let mut res = reqwest::get(&url).unwrap();
    let v: Value = match serde_json::from_str(&res.text().unwrap()) {
        Ok(x) => x,
        Err(x) => panic!("Failed to parse json\nReceived error {}", x),
    };

    match get_extract(&v) {
        Ok(x) => extract = x,
        Err(e) => pop_error(s, handler(e))
    };
    match get_links(&v) {
        Ok(x) => link_vec = x,
        Err(e) => pop_error(s, handler(e))
    };

    // get the act together
    let article_content = TextView::new(extract_formatter(extract)).scrollable();

    let links = SelectView::<String>::new()
        .with_all_str(link_vec)
        .on_submit(on_submit)
        .fixed_width(20);

    s.add_layer(
        Dialog::around(
            OnEventView::new(
                LinearLayout::horizontal()
                .child(article_content.fixed_width(72))
                .child(DummyView)
                .child(links)
                )
            .on_event('t', |s| match s.pop_layer() { _ => () })
            )
        .title(heading)
        );
}