@@ 1,22 @@
+Commands:
+ - watch
+ - sub
+ - unsub
+ - check
+ - e: search games/categories
+ - n: search streamers/channels
+ - game
+ - l
+ - player
+ - quality
+ - block
+ - implemented: adding to blocklist, printing to blocklist
+ - unimplemented: remove from blocklist
+ - version
+ - help
+
+Misc:
+ - colors
+ - debug/logging facilities
+ - translations
+ - environment.sh?<
\ No newline at end of file
@@ 1,140 @@
+use std::env;
+use std::fs;
+use std::io::prelude::*;
+use std::path::Path;
+
+// Twitch API information
+// This API key is intended to be used for wtwitch only -- do not use this API
+// key for any other reason!
+const TWITCH_API_URL: &str = "https://api.twitch.tv/helix";
+const TWITCH_ID_URL: &str = "https://id.twitch.tv/oauth2/token";
+const TWITCH_API_KEY: &str = "cotxsalhlctv8z572f7fant4b0sc3u";
+const TWITCH_API_SECRET: &str = "gaofxvult280l3sbz8n6btvk5fdswp";
+
+// Number of characters always present in print_game_info() output
+// 5 spaces, 1 colon, 2 parantheses
+const TITLE_CHARACTERS: &str = "8";
+
+fn main() {
+ // Get args
+ let cli_args: Vec<String> = env::args().collect();
+
+ if cli_args.len() < 2 {
+ println!("Please specify a command, e.g. wtwitch c");
+ return;
+ }
+
+ // Set vars
+ let home_path = env::var("HOME").unwrap();
+
+ // Config
+ let config_path = format!("{}/wtwitch", load_config_path(&home_path));
+ let config_file = format!("{}/config.json", config_path);
+ let blocklist_file = format!("{}/blocklist", config_path);
+
+ // Cache
+ let cache_path = format!("{}/wtwitch", load_cache_path(&home_path));
+ let cache_offline_text_file = format!("{}/stream_offline.txt", cache_path);
+ let cache_online_text_file = format!("{}/stream_online.txt", cache_path);
+ let cache_game_id_file = format!("{}/gameids.json", cache_path);
+ let last_seen_path = format!("{}/lastSeen", cache_path);
+
+ // Create missing dirs, files
+ if let Err(why) = fs::create_dir_all(&config_path) {
+ panic!("Couldn't create config directory {}: {}", config_path, why);
+ }
+ // Creating last_seen_path also creates cache_path
+ if let Err(why) = fs::create_dir_all(&last_seen_path) {
+ panic!("Couldn't create config directory {}: {}", cache_path, why);
+ }
+
+ // Load data
+ let blocklist = load_blocklist(&blocklist_file);
+
+ // Parse user command
+ let command = &cli_args[1].chars().next().unwrap();
+ match command {
+ 'b' => block(cli_args, blocklist_file, blocklist),
+ _ => help()
+ }
+}
+
+// Loading, checking
+
+fn load_config_path(path_to_home: &str) -> String {
+ if let Ok(xdg_config_home) = env::var("XDG_CONFIG_HOME") {
+ xdg_config_home
+ } else {
+ format!("{}/.config", path_to_home)
+ }
+}
+
+fn load_cache_path(path_to_home: &str) -> String {
+ if let Ok(xdg_cache_home) = env::var("XDG_CACHE_HOME") {
+ xdg_cache_home
+ } else {
+ format!("{}/.cache", path_to_home)
+ }
+}
+
+fn load_blocklist(path_to_blocklist: &str) -> String {
+ let path = Path::new(&path_to_blocklist);
+
+ // Create blocklist file if not exists
+ if !path.exists() {
+ if let Err(why) = fs::File::create(&path) {
+ panic!("Couldn't create blocklist file {}: {}", path_to_blocklist, why);
+ }
+ }
+
+ // Open the path in read-only mode
+ let mut file = match fs::File::open(&path) {
+ Err(why) => panic!("couldn't open {}: {}", path.display(), why),
+ Ok(file) => file,
+ };
+
+ // Read the file contents into a string
+ let mut s = String::new();
+ match file.read_to_string(&mut s) {
+ Err(why) => panic!("couldn't read {}: {}", path.display(), why),
+ Ok(_) => s
+ }
+}
+
+// Commands
+
+fn block(args: Vec<String>, blocklist_file: String, blocklist: String) {
+ // args
+ // 0: path to binary
+ // 1: command ([b]lock)
+ // 2.. : all streamers to block
+
+ if args.len() == 2 {
+ // Print blocklist
+ println!("Blocklist:\n{}", blocklist);
+ } else {
+ let mut counter = 2;
+ let mut file_to_write = fs::OpenOptions::new()
+ .append(true)
+ .open(&blocklist_file)
+ .unwrap();
+ while counter < args.len() {
+ // Add args[counter] to blocklist file if not present,
+ // Delete args[counter] from blocklist if present
+ if !blocklist.contains(&args[counter]) {
+ if let Err(why) = writeln!(file_to_write, "{}", args[counter]) {
+ eprintln!("Couldn't write to file {}: {}", blocklist_file, why);
+ }
+
+ println!("Added {} to blocklist", args[counter]);
+ } else {
+ println!("Skipping {}, already in blocklist", args[counter]);
+ }
+ counter += 1;
+ }
+ }
+}
+
+fn help() {
+ unimplemented!("TODO: Implement print help")
+}<
\ No newline at end of file