add news and ma chart

This commit is contained in:
Tan, Kian-ting 2023-07-13 02:38:14 +08:00
parent aa9b6d6ed8
commit 720b7d3ed3
2 changed files with 94 additions and 34 deletions

View file

@ -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
);

View file

@ -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 = [];