add news and ma chart
This commit is contained in:
parent
aa9b6d6ed8
commit
720b7d3ed3
2 changed files with 94 additions and 34 deletions
108
src/main.rs
108
src/main.rs
|
@ -1,17 +1,20 @@
|
|||
#![feature(proc_macro_hygiene, decl_macro)]
|
||||
|
||||
|
||||
use anyhow; // Exception Handling
|
||||
use chrono::{TimeZone, Utc};
|
||||
use chrono::{TimeZone, Utc, NaiveDateTime};
|
||||
use curl::easy::Easy;
|
||||
use serde_json::{Result, Value}; // JSON
|
||||
use serde::Serialize;
|
||||
use serde_json::{Result, Value, Value::Array}; // JSON
|
||||
use std::collections::HashMap;
|
||||
use serde_json::Value::Array;
|
||||
use rocket_dyn_templates::Template;
|
||||
use rocket::{Rocket, Build};
|
||||
use round::round;
|
||||
use num_format::{Locale, WriteFormatted};
|
||||
use rss::Channel;
|
||||
use feed_rs::parser;
|
||||
|
||||
//use std::env;
|
||||
//use std::fs;
|
||||
|
||||
#[macro_use] extern crate rocket;
|
||||
|
||||
|
@ -23,6 +26,12 @@ enum Date {
|
|||
YearToDate}
|
||||
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
struct TemplateContext<'a> {
|
||||
main : HashMap<&'a str, Vec<String>>,
|
||||
news: Vec<HashMap<&'a str, String>>,
|
||||
}
|
||||
|
||||
impl Date {
|
||||
fn as_str(&self) -> String {
|
||||
match &self {
|
||||
|
@ -42,11 +51,11 @@ fn get_tw_stock_json(stock_id: String) -> String {
|
|||
let response_json: Value = serde_json::from_str(response_body.as_str()).unwrap();
|
||||
|
||||
|
||||
let mut stock_total_data = tw_stock_process_json(&response_json);
|
||||
let mut stock_main_data = tw_stock_process_json(&response_json);
|
||||
|
||||
let stock_total_data_json = serde_json::json!(stock_total_data);
|
||||
let stock_main_data_json = serde_json::json!(stock_main_data);
|
||||
|
||||
return stock_total_data_json.to_string();
|
||||
return stock_main_data_json.to_string();
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,7 +64,7 @@ fn tw_stock_process_json(response_json : &Value) -> HashMap<&str, Vec<String>>{
|
|||
|
||||
let days_in_unix_time = &response_json["chart"]["result"][0]["timestamp"];
|
||||
|
||||
let mut stock_total_data = HashMap::new();
|
||||
let mut stock_main_data = HashMap::new();
|
||||
|
||||
let days_in_custom_format = match days_in_unix_time {
|
||||
serde_json::Value::Array(days_vec) => days_vec
|
||||
|
@ -65,7 +74,7 @@ fn tw_stock_process_json(response_json : &Value) -> HashMap<&str, Vec<String>>{
|
|||
_ => vec![format!("Not a series of date")],
|
||||
};
|
||||
|
||||
stock_total_data.insert("date", days_in_custom_format);
|
||||
stock_main_data.insert("date", days_in_custom_format);
|
||||
|
||||
let mut open_prices : Vec<String> = vec![];
|
||||
let mut close_prices : Vec<String> = vec![];
|
||||
|
@ -101,35 +110,81 @@ fn tw_stock_process_json(response_json : &Value) -> HashMap<&str, Vec<String>>{
|
|||
_ => (),
|
||||
}
|
||||
|
||||
stock_total_data.insert("open", open_prices);
|
||||
stock_total_data.insert("close", close_prices);
|
||||
stock_total_data.insert("high", high_prices);
|
||||
stock_total_data.insert("low", low_prices);
|
||||
stock_total_data.insert("volume", volumes);
|
||||
stock_main_data.insert("open", open_prices);
|
||||
stock_main_data.insert("close", close_prices);
|
||||
stock_main_data.insert("high", high_prices);
|
||||
stock_main_data.insert("low", low_prices);
|
||||
stock_main_data.insert("volume", volumes);
|
||||
|
||||
return stock_total_data;
|
||||
return stock_main_data;
|
||||
}
|
||||
|
||||
#[get("/<stock_id>")]
|
||||
fn get_tw_stock(stock_id: String) -> Template {
|
||||
|
||||
let rss_content = get_rss_data(stock_id.as_str());
|
||||
println!("{:}", rss_content);
|
||||
let rss_xml = get_rss_data(stock_id.as_str());
|
||||
|
||||
//let rss_xml = fs::read_to_string("/tmp/a.rss")
|
||||
// .expect("Should have been able to read the file");
|
||||
|
||||
let rss_parsed = parser::parse(rss_xml.as_bytes()).unwrap();
|
||||
|
||||
|
||||
let response_body = get_stock_data(stock_id.as_str(), Date::Day(1), Date::YearToDate);
|
||||
let response_json: Value = serde_json::from_str(response_body.as_str()).unwrap();
|
||||
|
||||
|
||||
let mut stock_total_data = tw_stock_process_json(&response_json);
|
||||
stock_total_data.insert("stock_id", vec![stock_id]);
|
||||
|
||||
stock_total_data.insert("news", vec![rss_content]);
|
||||
let mut stock_main_data = tw_stock_process_json(&response_json);
|
||||
stock_main_data.insert("stock_id", vec![stock_id]);
|
||||
|
||||
|
||||
let mut stock_total_data_by_date = transverse_stock_data_by_date(stock_total_data.clone());
|
||||
//let mut stock_total_data_by_date_wrapper = HashMap::new();
|
||||
let mut rss_entries = vec![];
|
||||
|
||||
//stock_total_data_by_date_wrapper.insert("data", stock_total_data_by_date);
|
||||
for i in 0..rss_parsed.entries.len(){
|
||||
let mut rss_entry = HashMap::new();
|
||||
//let title = i.title.clone().unwrap().content;
|
||||
//println!("{:}", title);
|
||||
let title = &rss_parsed.entries[i].title;
|
||||
|
||||
let title_string = match title {
|
||||
Some(a) => a.clone().content,
|
||||
_ => "title reading error".to_string(),
|
||||
};
|
||||
rss_entry.insert("title", title_string);
|
||||
|
||||
|
||||
let time = &rss_parsed.entries[i].published;
|
||||
let date_string = match time {
|
||||
Some(a) => {
|
||||
|
||||
format!("{}", a.format("%Y-%m-%d"))},
|
||||
_ => "time reading error".to_string(),
|
||||
};
|
||||
rss_entry.insert("date", date_string);
|
||||
|
||||
|
||||
let link = &rss_parsed.entries[i].links[0].href;
|
||||
rss_entry.insert("link", link.to_string());
|
||||
|
||||
let summary = &rss_parsed.entries[i].summary;
|
||||
let summary_string = match summary {
|
||||
Some(a) => a.clone().content,
|
||||
_ => "summary reading error".to_string(),
|
||||
};
|
||||
rss_entry.insert("summary", summary_string);
|
||||
|
||||
rss_entries.push(rss_entry);
|
||||
}
|
||||
|
||||
println!("{:?}", rss_entries);
|
||||
|
||||
|
||||
|
||||
let stock_total_data = TemplateContext{main : stock_main_data.clone(), news : rss_entries};
|
||||
|
||||
let mut stock_main_data_by_date = transverse_stock_data_by_date(stock_main_data.clone());
|
||||
//let mut stock_main_data_by_date_wrapper = HashMap::new();
|
||||
|
||||
//stock_main_data_by_date_wrapper.insert("data", stock_main_data_by_date);
|
||||
|
||||
return Template::render("tw_stock", stock_total_data);
|
||||
}
|
||||
|
@ -168,8 +223,7 @@ fn transverse_stock_data_by_date(orig_data : HashMap<&str, Vec<String>>) ->
|
|||
}
|
||||
|
||||
fn get_rss_data(stock_id : &str) -> String{
|
||||
let url = format!(
|
||||
"https://tw.stock.yahoo.com/rss?s={:}",
|
||||
let url = format!("https://tw.stock.yahoo.com/rss?s={:}",
|
||||
stock_id
|
||||
);
|
||||
|
||||
|
|
|
@ -108,8 +108,8 @@
|
|||
|
||||
<html>
|
||||
<body>
|
||||
<h2 id="stock_id">{{stock_id.0}}</h2>
|
||||
(<a href="{{stock_id.0}}/json">JSON</a>)
|
||||
<h2 id="stock_id">{{main.stock_id.0}}</h2>
|
||||
(<a href="{{main.stock_id.0}}/json">JSON</a>)
|
||||
<div id="css-table">
|
||||
<div class="css-tr">
|
||||
<div class="css-td"><table id="stock-table">
|
||||
|
@ -121,16 +121,17 @@
|
|||
<th>最低</th>
|
||||
<th>成交量</th>
|
||||
</tr>
|
||||
{{#with main}}
|
||||
{{#each date}}
|
||||
<tr id={{this}}>
|
||||
<td id="date">{{this}}</td>
|
||||
<td class="date">{{this}}</td>
|
||||
<td class="open">{{lookup ../open @index}}</td>
|
||||
<td class="close">{{lookup ../close @index}}</td>
|
||||
<td class="high">{{lookup ../high @index}}</td>
|
||||
<td class="low">{{lookup ../low @index}}</td>
|
||||
<td class="volume">{{lookup ../volume @index}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
{{/each}}{{/with}}
|
||||
</table></div><div>
|
||||
|
||||
<h3 id="chart-title"></h3>
|
||||
|
@ -140,8 +141,13 @@
|
|||
<input type="radio" name="range" value="ytd" checked="checked">今年迄今<br>
|
||||
<svg id="chart"></svg></div>
|
||||
|
||||
<div class="css-td">
|
||||
<div id="news_content">{{#each news}}foo:{{/each}}</div></div>
|
||||
<div class="css-td"><h3 id="chart-title">Yahoo 股市新聞</h3>
|
||||
<div id="news_content">{{#each news}}
|
||||
<div><div class="news-title"><a href="link">{{this.title}}</a></div>
|
||||
<div class="news-date">{{this.date}}</div>
|
||||
<div class="news-summary">{{this.summary}}……</div>
|
||||
|
||||
{{/each}}</div></div>
|
||||
</div></div>
|
||||
|
||||
<script src="http://d3js.org/d3.v4.min.js"></script>
|
||||
|
@ -211,7 +217,7 @@
|
|||
|
||||
|
||||
|
||||
d3.json(`{{stock_id.0}}/json`, function(d) {
|
||||
d3.json(`{{main.stock_id.0}}/json`, function(d) {
|
||||
console.log(d);
|
||||
|
||||
var data_by_date = [];
|
||||
|
|
Loading…
Reference in a new issue