This commit is contained in:
Matthew Ryan Dillon 2025-05-10 15:37:35 -04:00
parent f3c3eb338e
commit d050cecc0e
5 changed files with 2038 additions and 0 deletions

39
.gitignore vendored Normal file
View file

@ -0,0 +1,39 @@
# Rust
/target/
**/*.rs.bk
# By default, Cargo will ignore "Cargo.lock" for libraries, but include for binaries
Cargo.lock
# Next line is for macOS Finder/Spotlight
.DS_Store
# VSCode/
.vscode/
# CLion
.idea/
# Other common
*.log
*.tmp
*.swp
*.swo
*.bak
*~
# dotenv, custom local env/config
.env
.env.*
*.local
# compiled output
*.out
*.exe
*.bin
*.o
*.obj
# Coverage/test/artifacts
target/coverage/
coverage/

1873
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

11
Cargo.toml Normal file
View file

@ -0,0 +1,11 @@
[package]
name = "trmnl"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
toml = "0.8"
reqwest = { version = "0.12", features = ["json", "blocking"] }
dirs = "5"
chrono = "0.4"

38
src/config.rs Normal file
View file

@ -0,0 +1,38 @@
use dirs::config_dir;
use serde::Deserialize;
use std::fs;
use std::path::PathBuf;
#[derive(Debug, Deserialize)]
pub struct Config {
pub weather_api_key: String,
pub pollen_api_key: String,
pub calendar_api_key: String,
pub shopify_api_key: String,
pub shopify_store: String,
pub calendar_event_count: usize,
pub location: String,
}
impl Config {
pub fn load() -> Result<Self, Box<dyn std::error::Error>> {
// Try primary platform config_dir first (macOS: ~/Library/Application Support/trmnl/config.toml, Linux: ~/.config/trmnl/config.toml)
let mut config_path = config_dir().ok_or("Could not find user config directory")?;
config_path.push("trmnl/config.toml");
if config_path.exists() {
let contents = fs::read_to_string(&config_path)?;
let config: Config = toml::from_str(&contents)?;
return Ok(config);
}
// Fallback: try ~/.config/trmnl/config.toml explicitly
if let Some(home_dir) = dirs::home_dir() {
let fallback_path: PathBuf = home_dir.join(".config/trmnl/config.toml");
if fallback_path.exists() {
let contents = fs::read_to_string(&fallback_path)?;
let config: Config = toml::from_str(&contents)?;
return Ok(config);
}
}
Err("Config file not found in either location".into())
}
}

77
src/main.rs Normal file
View file

@ -0,0 +1,77 @@
mod config;
use config::Config;
fn main() {
// Load config
let config = match Config::load() {
Ok(cfg) => cfg,
Err(e) => {
eprintln!("Failed to load config: {e}");
std::process::exit(1);
}
};
// Weather
let (temp, conditions, high, low, forecast) = get_weather(&config);
println!("Weather for today:");
println!(" - Temperature: {temp}");
println!(" - Conditions: {conditions}");
println!(" - High: {high}, Low: {low}");
println!(" - Forecast: {forecast}");
// Pollen count
let pollen = get_pollen_count(&config);
println!("\nPollen count: {pollen}");
// Calendar events
println!("\nUpcoming calendar events:");
let events = get_calendar_events(&config, config.calendar_event_count);
for (i, event) in events.iter().enumerate() {
println!("{}. {}", i + 1, event);
}
// Shopify inbound packages
println!("\nInbound Shopify packages:");
let packages = get_shopify_packages(&config);
for (i, pkg) in packages.iter().enumerate() {
println!("{}. {}", i + 1, pkg);
}
}
// Placeholder stubs, replace with actual API calls later
fn get_weather(_config: &Config) -> (String, String, String, String, String) {
// TODO: Call weather API
(
"72°F".to_string(),
"Partly cloudy".to_string(),
"78°F".to_string(),
"65°F".to_string(),
"Mostly sunny, light breeze".to_string(),
)
}
fn get_pollen_count(_config: &Config) -> String {
// TODO: Call pollen count API
"Medium (Tree: 5, Grass: 2, Weed: 1)".to_string()
}
fn get_calendar_events(_config: &Config, n: usize) -> Vec<String> {
// TODO: Call calendar API
vec![
"Team meeting at 10:00 AM".to_string(),
"Lunch with Alex at 12:30 PM".to_string(),
"Dentist appointment at 3:00 PM".to_string(),
]
.into_iter()
.take(n)
.collect()
}
fn get_shopify_packages(_config: &Config) -> Vec<String> {
// TODO: Call Shopify API
vec![
"Order #1234: Shipped - Arriving May 13".to_string(),
"Order #5678: In transit - Arriving May 15".to_string(),
]
}