From 3a8255062e380b42aeefe1be101cce9d8d033c91 Mon Sep 17 00:00:00 2001 From: Mars Ultor Date: Sat, 11 Jan 2025 17:30:18 -0600 Subject: [PATCH] backend is done --- stock_news_publisher/Cargo.lock | 105 ++++++++++++++++++++----------- stock_news_publisher/Cargo.toml | 7 ++- stock_news_publisher/src/main.rs | 60 ++++++++++++++++-- 3 files changed, 129 insertions(+), 43 deletions(-) diff --git a/stock_news_publisher/Cargo.lock b/stock_news_publisher/Cargo.lock index 01d2c01..2464a57 100644 --- a/stock_news_publisher/Cargo.lock +++ b/stock_news_publisher/Cargo.lock @@ -17,6 +17,21 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "arc-swap" version = "1.7.1" @@ -68,12 +83,6 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.9.0" @@ -95,6 +104,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + [[package]] name = "colored" version = "2.2.0" @@ -432,6 +455,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icu_collections" version = "1.5.0" @@ -796,12 +842,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "percent-encoding" version = "2.3.1" @@ -928,28 +968,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rmp" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - -[[package]] -name = "rmp-serde" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" -dependencies = [ - "byteorder", - "rmp", - "serde", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1164,12 +1182,14 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" name = "stock_news_publisher" version = "0.1.0" dependencies = [ + "chrono", "log", "redis", "reqwest", - "rmp-serde", "serde", + "serde_json", "simple_logger", + "urlencoding", ] [[package]] @@ -1494,6 +1514,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf16_iter" version = "1.0.5" @@ -1640,6 +1666,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-registry" version = "0.2.0" diff --git a/stock_news_publisher/Cargo.toml b/stock_news_publisher/Cargo.toml index 346b48e..eb77272 100644 --- a/stock_news_publisher/Cargo.toml +++ b/stock_news_publisher/Cargo.toml @@ -8,5 +8,8 @@ log = "0.4.24" simple_logger = "5.0.0" redis = "0.28.0" reqwest = {version = "0.12.12", features = ["blocking"]} -rmp-serde = "1.3.0" -serde = "1.0.217" +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } +urlencoding = "2.1.3" +chrono = "0.4" + diff --git a/stock_news_publisher/src/main.rs b/stock_news_publisher/src/main.rs index 157fda3..08752d0 100644 --- a/stock_news_publisher/src/main.rs +++ b/stock_news_publisher/src/main.rs @@ -1,7 +1,10 @@ -use log::info; +use log::{debug, info}; use redis::{Client, Commands}; -use std::thread; - +use std::{thread::{self, sleep}, time::{Duration, Instant}}; +use serde_json::Value; +use serde::{Deserialize, Serialize}; +use urlencoding::*; +use chrono::Local; pub const NEWS_API_KEY: &str = "QdRyR4ztkKKeBq8btsOW0QVpiHWPQDnCRa6rBUkG"; fn main() { println!("Hello, world!"); @@ -9,14 +12,59 @@ fn main() { info!("Logging operational"); // program the publpisher here - let client = Client::open("redis::/192.168.1.23/").unwrap(); + let client = Client::open("redis://192.168.1.23/").unwrap(); let mut connection = client.get_connection().unwrap(); + + loop{ + let query_url: String = format!("https://api.marketaux.com/v1/news/all/?api_token={}&countries={}&sentiment_gte={}&sentiment_lte={}&language={}&published_after={}&limit={}", NEWS_API_KEY.clone(), encode("us,ca").into_owned(),encode(0.25f32.to_string().as_str()).into_owned(), encode((-0.25f32).to_string().as_str()).into_owned(), "en", + encode((Local::now() - Duration::from_secs(20*60)).format("%Y-%m-%dT%H:%M:%S").to_string().as_str()).into_owned(), 10); + info!(" Query url: {}", query_url); + let response_batch = reqwest::blocking::get(query_url.as_str()).unwrap().text().unwrap(); + debug!("Query has returned: {}", response_batch); + let returned: Value = serde_json::from_str(response_batch.as_str()).unwrap(); + let articles: Vec = returned.get("data").unwrap().as_array().unwrap().to_vec(); + + let bytes_to_publish: String = serde_json::to_string(&strip_and_construct(articles)).unwrap(); + + let _: () = connection.publish("notifications", bytes_to_publish).unwrap(); + + sleep(Duration::from_secs(60*20)); + } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] struct Notification{ - + title: String, + description: String, + url: String, + image_url: String, + tickers: Vec +} + +fn strip_and_construct(articles: Vec) -> Vec{ + let mut returnable: Vec = Vec::new(); + + for object in articles{ + let title: String = object.get("title").unwrap().as_str().unwrap().to_string(); + let description: String = object.get("description").unwrap().as_str().unwrap().to_string(); + let url: String = object.get("url").unwrap().as_str().unwrap().to_string(); + let image_url: String = object.get("image_url").unwrap().as_str().unwrap().to_string(); + + let entities: Vec = object.get("entities").unwrap().as_array().unwrap().to_vec(); + + let mut tickers: Vec = Vec::new(); + + for entity in entities{ + tickers.push(entity.get("symbol").unwrap().as_str().unwrap().to_string()); + } + + returnable.push(Notification { title, description, url, image_url, tickers}); + } + + + + return returnable; }