web requests

disabled by default because i don't really want to get ratelimited, and
 it's nice. caching will probably end up disabled for release builds, or
 i will host some static files on a local server.
This commit is contained in:
phyto 2023-02-13 11:59:59 +00:00
parent 38caea31e5
commit cd99a638b7
Signed by: phyto
SSH Key Fingerprint: SHA256:FJdIUDW+Q/c/oLlaNI7vrxCrv0VMxMgT6usJ+7A/wo0
3 changed files with 45 additions and 23 deletions

View File

@ -9,3 +9,4 @@ edition = "2021"
cursive = "0.20.0"
open = "3.2.0"
select = "0.6.0"
reqwest = { version = "0.11", features = ["blocking", "json"] }

View File

@ -9,7 +9,7 @@ pub struct Entry {
use select::predicate::*;
impl Entry {
pub fn new(node: &select::node::Node) -> Result<Self, Box<dyn std::error::Error>> {
pub fn from_lobsters(node: &select::node::Node) -> Result<Self, Box<dyn std::error::Error>> {
Ok(Self {
title: node
.find(Class("u-url"))
@ -34,6 +34,9 @@ impl Entry {
}
impl Entry {
pub fn summary(&self) -> String {
format!("{:<3} {}", self.score, self.title)
}
pub fn title(&self) -> &str {
&self.title
}
@ -46,3 +49,17 @@ impl Entry {
self.score
}
}
pub fn parse_frontpage_entries(html_root: &str) -> Result<Vec<Entry>, Box<dyn std::error::Error>> {
use select::document::Document;
use select::predicate::{Attr, Class, Name, Predicate};
let document = Document::from(html_root);
let entries = document
.find(Class("story"))
.map(|n| Entry::from_lobsters(&n).unwrap())
.collect::<Vec<Entry>>();
Ok(entries)
}

View File

@ -6,19 +6,9 @@ use select::predicate::{Attr, Class, Name, Predicate};
mod entry;
use entry::Entry;
fn fetch_frontpage_entries() -> Result<Vec<Entry>, Box<dyn std::error::Error>> {
let document = Document::from(include_str!("index.html"));
let entries = document
.find(Class("story"))
.map(|n| Entry::new(&n).unwrap())
.collect::<Vec<Entry>>();
Ok(entries)
}
use cursive::event::EventResult;
use cursive::traits::*;
use cursive::views::{Button, Dialog, DummyView, LinearLayout, SelectView};
use cursive::views::{Button, Dialog, DummyView, LinearLayout, OnEventView, SelectView, TextView};
use cursive::Cursive;
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -33,10 +23,12 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
}
let postlist = SelectView::<Entry>::new()
.on_submit(open_url)
.with_name("postlist")
.full_screen();
let buttons = LinearLayout::vertical()
.child(Button::new("Open URL", open_url))
//.child(Button::new("Open URL", open_url))
//.child(Button::new("Delete", delete_name))
.child(DummyView)
.child(Button::new("Quit", Cursive::quit));
@ -51,9 +43,23 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
.title("Lobste.rs posts"),
);
for e in fetch_frontpage_entries()? {
let html_root: String;
if !cfg!(nocache) {
html_root = include_str!("index.html").to_owned();
} else {
let client = reqwest::blocking::Client::builder()
.user_agent("slipper")
.build()?;
let req = client.get("https://lobste.rs/").send()?;
dbg!(&req);
html_root = req.text()?;
dbg!(&html_root);
}
for e in entry::parse_frontpage_entries(&html_root)? {
siv.call_on_name("postlist", |view: &mut SelectView<Entry>| {
view.add_item(e.clone().title(), e);
view.add_item(e.clone().summary(), e);
});
}
@ -62,11 +68,9 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
fn open_url(s: &mut Cursive) {
s.call_on_name("postlist", |v: &mut SelectView<Entry>| {
match v.selection() {
None => (),
Some(entry) => if let Ok(()) = open::that(entry.url()) {},
}
});
fn open_url(s: &mut Cursive, entry: &Entry) {
match open::that(entry.url()) {
Ok(()) => (),
Err(e) => s.add_layer(Dialog::info(format!("Error opening URL!\n{e}"))),
}
}