new history format

pull/6/head
dvkt 5 years ago
parent 1191da09f5
commit 8f467fea56

@ -52,11 +52,11 @@ Just unzip/untar the `phetch` program into your $PATH and get going!
## todo
- [ ] telnet: gopher://bitreich.org/1/lawn/bbs
- [ ] redo history view
- [ ] flesh out help
- [ ] new screenshots
- [ ] little GIF screencast in README
- [ ] telnet: gopher://bitreich.org/1/lawn/bbs
- [ ] bookmarks (ctrl+s, ctrl+b)
## bugs
@ -65,6 +65,5 @@ Just unzip/untar the `phetch` program into your $PATH and get going!
## future features
- [ ] bookmarks (ctrl+s, ctrl+b)
- [ ] TLS https://dataswamp.org/~solene/2019-03-07-gopher-server-tls.html
- [ ] Fuzzy Find incremental search

@ -4,7 +4,7 @@ pub fn lookup(name: &str) -> Option<String> {
Some(match name {
"" | "/" | "help" => format!("{}{}", HEADER, HELP),
"home" => format!("{}{}", HEADER, HOME),
"history" => history::load_as_raw_menu().unwrap_or_else(|| String::new()),
"history" => history::load_as_raw_menu(),
"bookmarks" => format!("{}", "3Coming soon"),
"keys" => format!("{}{}", HEADER, KEYS),
"nav" => format!("{}{}", HEADER, NAV),

@ -1,72 +1,77 @@
use gopher;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::io::{BufRead, BufReader, Result, Write};
pub fn load_as_raw_menu() -> Option<String> {
const CONFIG_DIR: &str = "~/.config/phetch/";
const HISTORY_FILE: &str = "history.gph";
/// History file is saved in ~/.config/phetch/history.gph if the phetch
/// config directory exists.
pub fn load_as_raw_menu() -> String {
let mut out = vec![];
if let Some(reader) = load() {
let mut lines = reader.lines();
while let Some(Ok(url)) = lines.next() {
let (t, host, port, sel) = gopher::parse_url(&url);
out.insert(
0,
format!(
"{}{}\t{}\t{}\t{}",
gopher::char_for_type(t).unwrap_or('i'),
url,
sel,
host,
port
),
);
match load() {
Ok(reader) => {
let mut lines = reader.lines();
while let Some(Ok(line)) = lines.next() {
out.insert(0, line); // reverse order
}
}
Err(e) => out.push(format!("3{}", e)),
}
out.insert(0, "i~/.config/phetch/history:\r\ni".into());
Some(out.join("\r\n"))
out.insert(0, format!("i{}{}:\r\ni", CONFIG_DIR, HISTORY_FILE));
out.join("\r\n")
}
pub fn load() -> Option<BufReader<File>> {
pub fn load() -> Result<BufReader<File>> {
let dotdir = config_dir_path();
if dotdir.is_none() {
return None;
return Err(error!("{} directory doesn't exist", CONFIG_DIR));
}
let history = dotdir.unwrap().join("history");
if let Ok(file) = std::fs::OpenOptions::new().read(true).open(history) {
return Some(BufReader::new(file));
let history = dotdir.unwrap().join(HISTORY_FILE);
if let Ok(file) = std::fs::OpenOptions::new().read(true).open(&history) {
return Ok(BufReader::new(file));
}
None
Err(error!("Couldn't open {:?}", history))
}
pub fn save(urls: &[impl std::fmt::Display]) {
// save a single history entry
pub fn save(url: &str, label: &str) {
let dotdir = config_dir_path();
if dotdir.is_none() {
return;
}
let dotdir = dotdir.unwrap();
let mut out = String::new();
for url in urls {
out.push_str(url.to_string().as_ref());
out.push('\n');
}
let history = dotdir.join("history");
let history = dotdir.join(HISTORY_FILE);
if let Ok(mut file) = std::fs::OpenOptions::new()
.append(true)
.create(true)
.open(history)
{
file.write_all(out.as_ref());
let (t, host, port, sel) = gopher::parse_url(&url);
file.write_all(
format!(
"{}{}\t{}\t{}\t{}\r\n",
gopher::char_for_type(t).unwrap_or('i'),
label,
sel,
host,
port
)
.as_ref(),
);
}
}
// Returns None if the config dir doesn't exist.
pub fn config_dir_path() -> Option<std::path::PathBuf> {
let homevar = std::env::var("HOME");
if homevar.is_err() {
return None;
}
let dotdir = "~/.config/phetch".replace('~', &homevar.unwrap());
let dotdir = CONFIG_DIR.replace('~', &homevar.unwrap());
let dotdir = std::path::Path::new(&dotdir);
if dotdir.exists() {
Some(std::path::PathBuf::from(dotdir))

@ -1,8 +1,11 @@
use gopher;
use gopher::Type;
use std::fmt;
use std::io::stdout;
use std::io::Write;
use std::thread;
use gopher;
use gopher::Type;
use history;
use ui;
use ui::{Action, Key, View, MAX_COLS, SCROLL_LINES};
@ -478,7 +481,12 @@ impl Menu {
}
Type::Error => Action::Error(line.name.to_string()),
Type::Telnet => Action::Error("Telnet support coming soon".into()),
_ => Action::Open(url),
_ => {
let hurl = url.to_string();
let hname = line.name.clone();
thread::spawn(move || history::save(&hurl, &hname));
Action::Open(url)
}
}
} else {
Action::None

@ -17,7 +17,6 @@ use termion::terminal_size;
use gopher;
use gopher::Type;
use help;
use history;
use menu::Menu;
use text::Text;
@ -167,9 +166,7 @@ impl UI {
fn startup(&mut self) {}
fn shutdown(&self) {
history::save(&self.views);
}
fn shutdown(&self) {}
fn term_size(&mut self, cols: usize, rows: usize) {
self.size = (cols, rows);

Loading…
Cancel
Save