Use indicatif for console output #3

Merged
falso merged 3 commits from indicatif into master 2021-12-26 21:54:35 +00:00
3 changed files with 106 additions and 94 deletions

120
Cargo.lock generated
View File

@ -23,17 +23,6 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
@ -87,9 +76,9 @@ name = "chaturbate"
version = "0.1.0"
dependencies = [
"config",
"log",
"console",
"indicatif",
"scraper",
"simple_logger",
"subprocess",
"ureq",
]
@ -100,17 +89,6 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
[[package]]
name = "colored"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]]
name = "config"
version = "0.11.0"
@ -127,6 +105,21 @@ dependencies = [
"yaml-rust",
]
[[package]]
name = "console"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"regex",
"terminal_size",
"unicode-width",
"winapi",
]
[[package]]
name = "const_fn"
version = "0.4.8"
@ -146,7 +139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f1c7727e460397e56abc4bddc1d49e07a1ad78fc98eb2e1c8f032a58a2f80d"
dependencies = [
"percent-encoding",
"time 0.2.27",
"time",
"version_check",
]
@ -163,7 +156,7 @@ dependencies = [
"publicsuffix",
"serde 1.0.131",
"serde_json",
"time 0.2.27",
"time",
"url",
]
@ -243,6 +236,12 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encoding_rs"
version = "0.8.30"
@ -319,15 +318,6 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "html5ever"
version = "0.25.1"
@ -363,6 +353,18 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "indicatif"
version = "0.17.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "500f7e5a63596852b9bf7583fe86f9ad08e0df9b4eb58d12e9729071cb4952ca"
dependencies = [
"console",
"lazy_static",
"number_prefix",
"regex",
]
[[package]]
name = "instant"
version = "0.1.12"
@ -519,6 +521,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "number_prefix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "once_cell"
version = "1.8.0"
@ -936,19 +944,6 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]]
name = "simple_logger"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45b60258a35dc3cb8a16890b8fd6723349bfa458d7960e25e633f1b1c19d7b5e"
dependencies = [
"atty",
"colored",
"log",
"time 0.3.5",
"winapi",
]
[[package]]
name = "siphasher"
version = "0.3.7"
@ -1095,6 +1090,16 @@ dependencies = [
"utf-8",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "thin-slice"
version = "0.1.1"
@ -1111,22 +1116,11 @@ dependencies = [
"libc",
"standback",
"stdweb",
"time-macros 0.1.1",
"time-macros",
"version_check",
"winapi",
]
[[package]]
name = "time"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad"
dependencies = [
"itoa",
"libc",
"time-macros 0.2.3",
]
[[package]]
name = "time-macros"
version = "0.1.1"
@ -1137,12 +1131,6 @@ dependencies = [
"time-macros-impl",
]
[[package]]
name = "time-macros"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6"
[[package]]
name = "time-macros-impl"
version = "0.1.2"

View File

@ -18,5 +18,5 @@ ureq = { version = "2.4.0", features = ["cookies", "charset"]}
scraper = "0.12.0"
config = "0.11"
subprocess = "0.2.8"
log = "0.4"
simple_logger = "1.16.0"
indicatif = "0.17.0-beta.1"
console = "0.15.0"

View File

@ -1,18 +1,19 @@
use std::collections::HashMap;
use std::time::{Duration, Instant};
use std::{thread, time};
use log::LevelFilter;
use log::{info, error};
use std::error::Error;
use scraper::{Html, Selector};
use simple_logger::SimpleLogger;
use subprocess::{Popen, PopenConfig, Redirection};
use ureq::{AgentBuilder};
use std::error::Error;
use indicatif::{MultiProgress, ProgressBar};
use console::{style};
/// Represents an instance of youtube-dl subprocess and the the Instant when it started
struct Recording {
process: subprocess::Popen,
time: Instant,
progress: indicatif::ProgressBar,
}
/// Contains the HTTP client with cookies support
@ -21,7 +22,8 @@ struct Recording {
pub struct Chaturbate {
client: ureq::Agent,
settings: config::Config,
recording: HashMap<String, Recording>
recording: HashMap<String, Recording>,
progress: indicatif::MultiProgress,
}
impl Default for Chaturbate {
@ -33,11 +35,6 @@ impl Default for Chaturbate {
impl Chaturbate {
/// Returns a new Chaturbate client
pub fn new() -> Self {
// Initialize Logging
SimpleLogger::new()
.with_utc_timestamps()
.with_level(LevelFilter::Info)
.with_colors(true).init().unwrap();
// Initialize Settings
let mut settings = config::Config::default();
settings.merge(config::File::with_name("chaturbate")).unwrap();
@ -47,7 +44,7 @@ impl Chaturbate {
.timeout_read(Duration::from_secs(10))
.timeout_write(Duration::from_secs(10))
.build();
Self { client, settings, recording: HashMap::new() }
Self { client, settings, recording: HashMap::new(), progress: MultiProgress::new() }
}
/// Parses the HTML source to find out if the login worked
@ -69,8 +66,10 @@ impl Chaturbate {
}
/// Does an HTTP POST to login with the credentials from the settings
fn login(&mut self) -> Result<(), Box<dyn Error>> {
info!("Logging in");
fn login(&mut self) -> Result<(), Box<dyn Error>> {
let pb = self.progress.add(ProgressBar::new_spinner());
let msg = format!("{}", style("Logging in...").blue().bold());
pb.set_message(msg);
// Open the login page to get the CSRF Token
let response = self.client.get("https://chaturbate.com/auth/login/").call()?;
let html = response.into_string()?;
@ -97,16 +96,19 @@ impl Chaturbate {
.send_form(&params);
},
None => { error!("The csrf token input tag has no value") }
None => {}
};
},
None => { error!("Could not find the csrf token input tag") }
None => {}
};
Ok(())
}
/// Returns a list of the followed models that are currently online
fn get_online_models(&mut self) -> Result<Vec<String>, Box<dyn Error>> {
let pb = self.progress.add(ProgressBar::new_spinner());
let msg = format!("{}", style("Getting followed models that are online...").blue().bold());
pb.set_message(msg);
let mut models: Vec<String> = Vec::new();
// Get the followed list
let response = self.client.get("https://chaturbate.com/followed-cams/").call()?;
@ -154,6 +156,8 @@ impl Chaturbate {
}
models.push(name.to_string());
}
pb.finish_and_clear();
self.progress.remove(&pb);
Ok(models)
}
@ -182,8 +186,15 @@ impl Chaturbate {
let p = Popen::create(&["youtube-dl", "-q", url.as_ref()], PopenConfig {
stdout: Redirection::Pipe, stderr: Redirection::Merge, ..Default::default()
}).unwrap();
info!("Started recording {}", model);
let r = Recording { time: Instant::now(), process: p };
let msg = format!(
"{} {}",
style("Recording").red(),
style(model).green().bold(),
);
let pb = self.progress.add(ProgressBar::new_spinner());
//let pb = ProgressBar::new_spinner();
pb.set_message(msg);
let r = Recording { time: Instant::now(), process: p, progress: pb };
self.recording.insert(model.to_string(), r);
}
@ -199,18 +210,30 @@ impl Chaturbate {
}
for name in terminated {
let recording = self.recording.get(&name).unwrap();
let elapsed = recording.time.elapsed();
let extra: String = if elapsed < Duration::from_secs(10) {
String::from(" - probably private")
} else {
String::from("")
};
info!("Recording of {} finished after {:?}{}", name, elapsed, extra);
recording.progress.finish_and_clear();
self.progress.remove(&recording.progress);
// No longer recording it
self.recording.remove(&name);
}
}
fn animate(&mut self) {
let end = Instant::now() + Duration::from_secs(5);
while Instant::now() < end {
for (name, c) in &mut self.recording {
let msg = format!(
"{} {} - {:?}",
style("Recording").red(),
style(name).green().bold(),
c.time.elapsed()
);
c.progress.set_message(msg);
c.progress.tick();
}
thread::sleep(time::Duration::from_secs_f32(0.5));
}
}
/// Main loop
pub fn do_cycle(&mut self) {
// Get online models, and start recording them
@ -222,14 +245,15 @@ impl Chaturbate {
// Print how many we are recording at the moment
let recording = self.recording.len();
if recording > 0 {
info!("Currently recording {} streams", recording);
//info!("Currently recording {} streams", recording);
}
// Sleep
let delay = self.settings.get_int("delay").unwrap() as u64;
let end = Instant::now() + Duration::from_secs(delay);
while Instant::now() < end {
self.clean_recordings();
thread::sleep(time::Duration::from_secs(5));
self.animate();
//thread::sleep(time::Duration::from_secs(5));
}
}
}