summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs124
1 files changed, 104 insertions, 20 deletions
diff --git a/src/main.rs b/src/main.rs
index 1dc3983..50b5e04 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,5 @@
use select::document::Document;
-use select::predicate::{Name, And, Class, Attr, Descendant, Any, Predicate};
+use select::predicate::{Name, Class, Predicate};
use select::node::{Node, Attrs};
use reqwest;
@@ -8,16 +8,35 @@ struct Post {
id: i32,
title: String,
source: String,
- points: i32,
+ score: i32,
author: String,
- comments: i32
}
-// fn getAttribute(attrs: Attrs, name: String) -> Option<String> {
-//
-// }
+impl Post {
+ pub fn to_string(&self) -> String {
+ return [
+ "Post {",
+ format!(" id: {}", self.id).as_str(),
+ format!(" title: {}", self.title).as_str(),
+ format!(" source: {}", self.source).as_str(),
+ format!(" score: {}", self.score).as_str(),
+ format!(" author: {}", self.author).as_str(),
+ "}"
+ ].join("\n");
+ }
+}
+
+fn get_attribute(attrs: Attrs, name: &str) -> Option<String> {
+ let name = String::from(name);
+ for (key, value) in attrs {
+ if String::from(key) == name {
+ return Some(String::from(value));
+ }
+ }
+ return None;
+}
-fn getPage(url: &str) -> Option<String> {
+fn get_page(url: &str) -> Option<String> {
match reqwest::blocking::get(url) {
Ok(res) => match res.text() {
Ok(text) => return Some(text),
@@ -27,20 +46,13 @@ fn getPage(url: &str) -> Option<String> {
}
}
-fn main() {
- let page = getPage("https://news.ycombinator.com/");
- let page = match page {
- Some(ref text) => text.as_str(),
- None => panic!("Returned page is empty)")
- };
-
- let doc = Document::from(page);
- let table = doc.find(Class("itemlist").descendant(Name("tbody")))
+fn parse_hackernews(document: Document) -> Vec<Post> {
+ let table = document.find(Class("itemlist").descendant(Name("tbody")))
.next()
.unwrap();
let mut nodes: Vec<Node> = Vec::new();
- for (idx, node) in table.children().enumerate() {
+ for node in table.children() {
if node.is(Class("morespace")) {
break;
}
@@ -49,10 +61,82 @@ fn main() {
}
}
+ println!("jopa1");
+ let mut posts: Vec<Post> = Vec::new();
for node in nodes.windows(2) {
- let link = node[0].find(Class("storylink")).next().unwrap();
+ let link = node[0].find(Class("storylink")).next();
+ let link = match link {
+ Some(node) => node,
+ None => continue
+ };
+
+ let id = get_attribute(node[0].attrs(), "id");
+ let id = match id {
+ Some(id) => {
+ match id.parse::<i32>() {
+ Ok(num) => num,
+ Err(_) => continue
+ }
+ },
+ None => continue
+ };
let title = link.text();
- println!("{}", link.html());
- println!("{}", title);
+ let source = get_attribute(link.attrs(), "href");
+ let source = match source {
+ Some(href) => href,
+ None => continue
+ };
+
+
+ let subscript = node[1].find(Class("subtext")).next();
+ let subscript = match subscript {
+ Some(node) => node,
+ None => continue
+ };
+
+ let score = subscript.find(Class("score")).next();
+ let score = match score {
+ Some(node) => {
+ let text = node.text();
+ let n_text = text.split(' ').collect::<Vec<&str>>()[0];
+ match n_text.parse::<i32>() {
+ Ok(num) => num,
+ Err(_) => continue
+ }
+ },
+ None => continue
+ };
+
+ let author = subscript.find(Class("hnuser")).next();
+ let author = match author {
+ Some(user) => user.text(),
+ None => continue
+ };
+
+ posts.push(Post {
+ id,
+ title,
+ source,
+ score,
+ author
+ });
+ }
+
+
+ return posts;
+}
+
+fn main() {
+ let page = get_page("https://news.ycombinator.com/");
+ let page = match page {
+ Some(ref text) => text.as_str(),
+ None => panic!("Returned page is empty)")
+ };
+
+ let doc = Document::from(page);
+ let posts = parse_hackernews(doc);
+
+ for post in posts {
+ println!("{}", post.to_string());
}
}