added fs stuff
This commit is contained in:
parent
c6c7808876
commit
9d71ba17a5
15
src/app.rs
15
src/app.rs
@ -1,8 +1,17 @@
|
|||||||
|
use ratatui::widgets::ListState;
|
||||||
|
|
||||||
|
use crate::config::*;
|
||||||
|
|
||||||
pub enum AppRenderDir {
|
pub enum AppRenderDir {
|
||||||
Vertical,
|
Vertical,
|
||||||
Horizontal,
|
Horizontal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum MenuState {
|
||||||
|
Main,
|
||||||
|
List,
|
||||||
|
}
|
||||||
|
|
||||||
pub enum CurrentState {
|
pub enum CurrentState {
|
||||||
Lookup,
|
Lookup,
|
||||||
Menu,
|
Menu,
|
||||||
@ -14,6 +23,9 @@ pub struct App {
|
|||||||
pub dns_info: Vec<String>,
|
pub dns_info: Vec<String>,
|
||||||
pub render_direction: AppRenderDir,
|
pub render_direction: AppRenderDir,
|
||||||
pub current_state: CurrentState,
|
pub current_state: CurrentState,
|
||||||
|
pub menu_state: MenuState,
|
||||||
|
pub config: Config,
|
||||||
|
pub state: ListState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
@ -24,6 +36,9 @@ impl App {
|
|||||||
dns_info: vec![],
|
dns_info: vec![],
|
||||||
render_direction: AppRenderDir::Vertical,
|
render_direction: AppRenderDir::Vertical,
|
||||||
current_state: CurrentState::Lookup,
|
current_state: CurrentState::Lookup,
|
||||||
|
menu_state: MenuState::Main,
|
||||||
|
config: Config::from_file("test.ini".to_string()),
|
||||||
|
state: ListState::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,12 @@ use std::error::Error;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use ratatui::{
|
||||||
|
style::{Modifier, Style},
|
||||||
|
text::{Line, Span},
|
||||||
|
widgets::ListItem,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -43,4 +49,17 @@ impl DomainData {
|
|||||||
Ok(())
|
Ok(())
|
||||||
// println!("{}", output);
|
// println!("{}", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_lookups(config: &Config) -> Vec<ListItem> {
|
||||||
|
let mut items: Vec<ListItem> = vec![];
|
||||||
|
for item in fs::read_dir(format!("{}/lookups", config.data_dir)).unwrap() {
|
||||||
|
let item_name = item.unwrap();
|
||||||
|
items.push(ListItem::new(Line::from(Span::styled(
|
||||||
|
String::from(item_name.path().to_string_lossy().clone()),
|
||||||
|
Style::default(),
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
55
src/main.rs
55
src/main.rs
@ -13,8 +13,8 @@ use crate::app::*;
|
|||||||
mod ui;
|
mod ui;
|
||||||
use crate::ui::*;
|
use crate::ui::*;
|
||||||
|
|
||||||
mod fs;
|
mod fsutil;
|
||||||
use crate::fs::*;
|
use crate::fsutil::*;
|
||||||
|
|
||||||
use crossterm::event::{
|
use crossterm::event::{
|
||||||
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind,
|
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind,
|
||||||
@ -41,7 +41,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
let config = Config::from_file("test.ini".to_string());
|
let config = Config::from_file("test.ini".to_string());
|
||||||
|
|
||||||
// Run the app
|
// Run the app
|
||||||
let _res = run_app(&mut terminal, &mut app, &config);
|
let _res = run_app(&mut terminal, &mut app);
|
||||||
|
|
||||||
disable_raw_mode()?;
|
disable_raw_mode()?;
|
||||||
execute!(
|
execute!(
|
||||||
@ -53,11 +53,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_app<B: Backend>(
|
fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: &mut App) -> io::Result<bool> {
|
||||||
terminal: &mut Terminal<B>,
|
|
||||||
app: &mut App,
|
|
||||||
config: &Config,
|
|
||||||
) -> io::Result<bool> {
|
|
||||||
loop {
|
loop {
|
||||||
terminal.draw(|f| ui(f, app))?;
|
terminal.draw(|f| ui(f, app))?;
|
||||||
|
|
||||||
@ -83,7 +79,7 @@ fn run_app<B: Backend>(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut domain = Domain::new(app.domain_input.clone());
|
let mut domain = Domain::new(app.domain_input.clone());
|
||||||
domain.apply_config(&config);
|
domain.apply_config(&app.config);
|
||||||
domain.lookup_all_records();
|
domain.lookup_all_records();
|
||||||
app.dns_info = domain.to_vec();
|
app.dns_info = domain.to_vec();
|
||||||
let whois = WhoisData::new(app.domain_input.clone());
|
let whois = WhoisData::new(app.domain_input.clone());
|
||||||
@ -94,21 +90,32 @@ fn run_app<B: Backend>(
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
CurrentState::Menu => match key.code {
|
CurrentState::Menu => match app.menu_state {
|
||||||
KeyCode::Esc => {
|
MenuState::Main => match key.code {
|
||||||
app.current_state = CurrentState::Lookup;
|
KeyCode::Esc => {
|
||||||
}
|
app.current_state = CurrentState::Lookup;
|
||||||
KeyCode::Char('s') => {
|
}
|
||||||
let domain_data = DomainData::new(
|
KeyCode::Char('s') => {
|
||||||
app.domain_input.clone(),
|
let domain_data = DomainData::new(
|
||||||
app.dns_info.clone(),
|
app.domain_input.clone(),
|
||||||
app.whois_info.clone(),
|
app.dns_info.clone(),
|
||||||
);
|
app.whois_info.clone(),
|
||||||
domain_data.save_lookup(&config).unwrap();
|
);
|
||||||
app.current_state = CurrentState::Lookup;
|
domain_data.save_lookup(&app.config).unwrap();
|
||||||
}
|
app.current_state = CurrentState::Lookup;
|
||||||
KeyCode::Char('q') => return Ok(false),
|
}
|
||||||
_ => {}
|
KeyCode::Char('l') => {
|
||||||
|
app.menu_state = MenuState::List;
|
||||||
|
}
|
||||||
|
KeyCode::Char('q') => return Ok(false),
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
MenuState::List => match key.code {
|
||||||
|
KeyCode::Esc => {
|
||||||
|
app.menu_state = MenuState::Main;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
142
src/ui.rs
142
src/ui.rs
@ -1,14 +1,17 @@
|
|||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
style::{Color, Style, Styled},
|
style::{Color, Modifier, Style, Styled},
|
||||||
text::{Line, Span, Text},
|
text::{Line, Span, Text},
|
||||||
widgets::{Block, Borders, Clear, List, ListItem, Paragraph, Wrap},
|
widgets::{
|
||||||
|
Block, Borders, Clear, HighlightSpacing, List, ListDirection, ListItem, ListState,
|
||||||
|
Paragraph, Wrap,
|
||||||
|
},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{App, AppRenderDir},
|
app::{App, AppRenderDir},
|
||||||
CurrentState,
|
CurrentState, DomainData, MenuState,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn ui(f: &mut Frame, app: &mut App) {
|
pub fn ui(f: &mut Frame, app: &mut App) {
|
||||||
@ -188,61 +191,104 @@ pub fn ui(f: &mut Frame, app: &mut App) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CurrentState::Menu => {
|
CurrentState::Menu => {
|
||||||
let chunks = Layout::default()
|
match app.menu_state {
|
||||||
.direction(Direction::Vertical)
|
MenuState::Main => {
|
||||||
.constraints([
|
let chunks = Layout::default()
|
||||||
Constraint::Length(3),
|
.direction(Direction::Vertical)
|
||||||
Constraint::Min(1),
|
.constraints([
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
])
|
Constraint::Min(1),
|
||||||
.split(f.size());
|
Constraint::Length(3),
|
||||||
|
])
|
||||||
|
.split(f.size());
|
||||||
|
|
||||||
let title_block = Block::new().borders(Borders::ALL).style(Style::default());
|
let title_block = Block::new().borders(Borders::ALL).style(Style::default());
|
||||||
|
|
||||||
let title = Paragraph::new(Text::styled(
|
let title = Paragraph::new(Text::styled(
|
||||||
"**** Menu ****",
|
"**** Menu ****",
|
||||||
Style::default().fg(Color::Cyan),
|
Style::default().fg(Color::Cyan),
|
||||||
))
|
))
|
||||||
.block(title_block);
|
.block(title_block);
|
||||||
f.render_widget(title, chunks[0]);
|
f.render_widget(title, chunks[0]);
|
||||||
|
|
||||||
let mut options_list = Vec::<ListItem>::new();
|
let mut options_list = Vec::<ListItem>::new();
|
||||||
options_list.push(ListItem::new(Line::from(Span::styled(
|
options_list.push(ListItem::new(Line::from(Span::styled(
|
||||||
"ESC) Return to lookup",
|
"ESC) Return to lookup",
|
||||||
Style::default(),
|
Style::default(),
|
||||||
))));
|
))));
|
||||||
|
|
||||||
// TODO: Add code to save lookup
|
// TODO: Add code to save lookup
|
||||||
options_list.push(ListItem::new(Line::from(Span::styled(
|
options_list.push(ListItem::new(Line::from(Span::styled(
|
||||||
"S) Save lookup",
|
"S) Save lookup",
|
||||||
Style::default(),
|
Style::default(),
|
||||||
))));
|
))));
|
||||||
|
|
||||||
// TODO: Add code to load and UI to list saved lookups
|
// TODO: Add code to load and UI to list saved lookups
|
||||||
options_list.push(ListItem::new(Line::from(Span::styled(
|
options_list.push(ListItem::new(Line::from(Span::styled(
|
||||||
"L) List previous lookups",
|
"L) List previous lookups",
|
||||||
Style::default(),
|
Style::default(),
|
||||||
))));
|
))));
|
||||||
|
|
||||||
// TODO: Add code to read lookup and display
|
// TODO: Add code to read lookup and display
|
||||||
options_list.push(ListItem::new(Line::from(Span::styled(
|
options_list.push(ListItem::new(Line::from(Span::styled(
|
||||||
"V) View previous lookup",
|
"V) View previous lookup",
|
||||||
Style::default(),
|
Style::default(),
|
||||||
))));
|
))));
|
||||||
|
|
||||||
options_list.push(ListItem::new(Line::from(Span::styled(
|
options_list.push(ListItem::new(Line::from(Span::styled(
|
||||||
"Q) Quit",
|
"Q) Quit",
|
||||||
Style::default(),
|
Style::default(),
|
||||||
))));
|
))));
|
||||||
|
|
||||||
let options = List::new(options_list);
|
let options = List::new(options_list);
|
||||||
f.render_widget(options, chunks[1]);
|
f.render_widget(options, chunks[1]);
|
||||||
|
|
||||||
let footer_block = Block::new().borders(Borders::ALL).style(Style::default());
|
let footer_block = Block::new().borders(Borders::ALL).style(Style::default());
|
||||||
|
|
||||||
let footer = Paragraph::new(Text::styled("[q] Quit", Style::default().fg(Color::Red)))
|
let footer =
|
||||||
.block(footer_block);
|
Paragraph::new(Text::styled("[q] Quit", Style::default().fg(Color::Red)))
|
||||||
f.render_widget(footer, chunks[2]);
|
.block(footer_block);
|
||||||
|
f.render_widget(footer, chunks[2]);
|
||||||
|
}
|
||||||
|
MenuState::List => {
|
||||||
|
let chunks = Layout::default()
|
||||||
|
.direction(Direction::Vertical)
|
||||||
|
.constraints([
|
||||||
|
Constraint::Length(3),
|
||||||
|
Constraint::Min(1),
|
||||||
|
Constraint::Length(3),
|
||||||
|
])
|
||||||
|
.split(f.size());
|
||||||
|
|
||||||
|
let title_block = Block::new().borders(Borders::ALL).style(Style::default());
|
||||||
|
|
||||||
|
let title = Paragraph::new(Text::styled(
|
||||||
|
"**** List ****",
|
||||||
|
Style::default().fg(Color::Cyan),
|
||||||
|
))
|
||||||
|
.block(title_block);
|
||||||
|
f.render_widget(title, chunks[0]);
|
||||||
|
|
||||||
|
let item_list = DomainData::list_lookups(&app.config);
|
||||||
|
let items = List::new(item_list)
|
||||||
|
.block(Block::default().title("Lookups").borders(Borders::ALL))
|
||||||
|
.style(Style::default())
|
||||||
|
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
|
||||||
|
.highlight_symbol(">>")
|
||||||
|
.highlight_spacing(HighlightSpacing::Always)
|
||||||
|
.repeat_highlight_symbol(true);
|
||||||
|
f.render_stateful_widget(items, chunks[1], &mut app.state);
|
||||||
|
|
||||||
|
let footer_block = Block::new().borders(Borders::ALL).style(Style::default());
|
||||||
|
|
||||||
|
let footer = Paragraph::new(Text::styled(
|
||||||
|
"[ESC] Return to menu",
|
||||||
|
Style::default().fg(Color::Red),
|
||||||
|
))
|
||||||
|
.block(footer_block);
|
||||||
|
f.render_widget(footer, chunks[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user