tidying up

This commit is contained in:
Love 2023-02-28 16:22:53 +01:00
parent 6197c52bf8
commit 41a4af4667
3 changed files with 43 additions and 33 deletions

View File

@ -10,6 +10,8 @@ use indicatif::{ProgressBar, ProgressState, ProgressStyle};
use reqwest::{self, Client}; use reqwest::{self, Client};
use std::cmp; use std::cmp;
use crate::get_mut_ref;
pub enum DualWriter { pub enum DualWriter {
File(File), File(File),
Buffer(Vec<u8>), Buffer(Vec<u8>),
@ -38,14 +40,14 @@ impl DualWriter {
let mut buf = String::new(); let mut buf = String::new();
// Well this is safe since I consume the file anyways // Well this is safe since I consume the file anyways
let ptr = &file as *const File as *mut File; let file = unsafe { get_mut_ref(&file) };
let file = unsafe { &mut *ptr };
file.read_to_string(&mut buf) file.read_to_string(&mut buf)
.or(Err("Failed to read file".to_owned()))?; .or(Err("Failed to read file".to_owned()))?;
buf buf
} }
}) })
} }
pub fn new(file_name: Option<&str>) -> Result<Self, io::Error> { pub fn new(file_name: Option<&str>) -> Result<Self, io::Error> {
Ok(if let Some(file_name) = file_name { Ok(if let Some(file_name) = file_name {
Self::File(File::create(&file_name)?) Self::File(File::create(&file_name)?)
@ -59,7 +61,7 @@ pub async fn download_with_progress(
link: &str, link: &str,
file_name: Option<&str>, file_name: Option<&str>,
) -> Result<DualWriter, String> { ) -> Result<DualWriter, String> {
let mut dw = DualWriter::new(file_name).or(Err("Failed to create file".to_owned()))?; let mut dual_writer = DualWriter::new(file_name).or(Err("Failed to create file".to_owned()))?;
let client = Client::builder() let client = Client::builder()
.gzip(true) .gzip(true)
@ -71,14 +73,14 @@ pub async fn download_with_progress(
.send() .send()
.await .await
.or(Err("Failed to connect server".to_owned()))?; .or(Err("Failed to connect server".to_owned()))?;
let content_length = if let Some(s) = resp.content_length() { let content_length = if let Some(got_content_length) = resp.content_length() {
s got_content_length
} else { } else {
panic!("Could not retrive content length from server. {:?}", &resp); panic!("Could not retrive content length from server. {:?}", &resp);
}; };
let pb = ProgressBar::new(content_length); let progress_bar = ProgressBar::new(content_length);
pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})").unwrap() progress_bar.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})").unwrap()
.with_key("eta", |state: &ProgressState, w: &mut dyn fmt::Write| write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap()) .with_key("eta", |state: &ProgressState, w: &mut dyn fmt::Write| write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap())
.progress_chars("#>-")); .progress_chars("#>-"));
@ -88,11 +90,12 @@ pub async fn download_with_progress(
while let Some(item) = stream.next().await { while let Some(item) = stream.next().await {
let bytes = item.unwrap(); let bytes = item.unwrap();
downloaded = cmp::min(downloaded + (bytes.len() as u64), content_length); downloaded = cmp::min(downloaded + (bytes.len() as u64), content_length);
dw.write(bytes) dual_writer
.write(bytes)
.or(Err("Failed to write to file".to_owned()))?; .or(Err("Failed to write to file".to_owned()))?;
pb.set_position(downloaded); progress_bar.set_position(downloaded);
} }
Ok(dw) Ok(dual_writer)
} }

View File

@ -63,3 +63,13 @@ impl<'a> Readline<'a> {
buffer buffer
} }
} }
/**
* I know that this isn't considered true rusty code, but the places it's used in is
* safe. For this I'll leave the funciton as unsafe, so to better see it's uses.
* This solution makes the uses BLAZINGLY FAST which moreover is the most rusty you can get.
*/
pub unsafe fn get_mut_ref<T>(reference: &T) -> &mut T {
let ptr = reference as *const T as *mut T;
&mut *ptr
}

View File

@ -3,7 +3,7 @@ use std::process::Command;
use std::rc::Rc; use std::rc::Rc;
use colored::Colorize; use colored::Colorize;
use iptvnator::{download_with_progress, setup, M3u8, Parser, Readline}; use iptvnator::{download_with_progress, get_mut_ref, setup, M3u8, Parser, Readline};
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
@ -52,7 +52,7 @@ async fn main() {
} }
search_result = Some(Rc::new(parser.find(search))); search_result = Some(Rc::new(parser.find(search)));
if search_result.as_ref().unwrap().len() == 0 { if search_result.as_ref().unwrap().is_empty() {
println!("Nothing found"); println!("Nothing found");
continue; continue;
} }
@ -95,8 +95,8 @@ async fn main() {
// Downloadmode // Downloadmode
"d" => { "d" => {
let to_download = let to_download =
ask_which_to_download(&mut readline, search_result.as_ref().unwrap().clone()); ask_which_to_download(&mut readline, &search_result.as_ref().unwrap());
download_m3u8(to_download).await; download_m3u8(&to_download).await;
} }
_ => {} _ => {}
} }
@ -104,8 +104,8 @@ async fn main() {
let choosen = user_wish.parse::<usize>(); let choosen = user_wish.parse::<usize>();
match choosen { match choosen {
Ok(k) => { Ok(k) => {
let search_result = search_result.as_ref().unwrap().clone(); let search_result = search_result.as_ref().unwrap();
stream(&(search_result[k - 1]), mpv_fs); stream(search_result[k - 1], mpv_fs);
parser.save_watched(); parser.save_watched();
} }
Err(e) => println!("Have to be a valid number! {:?}", e), Err(e) => println!("Have to be a valid number! {:?}", e),
@ -115,7 +115,7 @@ async fn main() {
fn ask_which_to_download<'a>( fn ask_which_to_download<'a>(
readline: &mut Readline, readline: &mut Readline,
search_result: Rc<Vec<&'a M3u8>>, search_result: &Rc<Vec<&'a M3u8>>,
) -> Rc<Vec<&'a M3u8>> { ) -> Rc<Vec<&'a M3u8>> {
let selections = loop { let selections = loop {
// Ask for userinput // Ask for userinput
@ -155,17 +155,7 @@ fn ask_which_to_download<'a>(
) )
} }
/* async fn download_m3u8(files_to_download: &Vec<&M3u8>) {
* I know that this is also frowned upon, but it is perfectly safe right here,
* even though the borrowchecker complains
*/
async fn refresh(parser: &Parser) {
let ptr = parser as *const Parser as *mut Parser;
let p = unsafe { &mut *ptr };
p.forcefully_update().await;
}
async fn download_m3u8(files_to_download: Rc<Vec<&M3u8>>) {
for m3u8 in files_to_download.iter() { for m3u8 in files_to_download.iter() {
let file_ending_place = m3u8.link.rfind(".").unwrap(); let file_ending_place = m3u8.link.rfind(".").unwrap();
let potential_file_ending = &m3u8.link[file_ending_place..]; let potential_file_ending = &m3u8.link[file_ending_place..];
@ -183,14 +173,13 @@ async fn download_m3u8(files_to_download: Rc<Vec<&M3u8>>) {
} }
/** /**
* This function uses unsafe code to change an atribute, and while I know that this is not * I know that this is not how youre supposed to do things, but it's perfectly safe
* how youre supposed to do things, it's perfectly safe in this context and also the most efficient way. * in this context and also the most efficient way.
* With other words, it's BLAZINGLY FAST * With other words, it's BLAZINGLY FAST
*/ */
fn stream(m3u8item: &M3u8, launch_in_fullscreen: bool) { fn stream(m3u8item: &M3u8, launch_in_fullscreen: bool) {
let ptr = m3u8item as *const M3u8 as *mut M3u8; let mut m3u8item = unsafe { get_mut_ref(m3u8item) };
let mut item = unsafe { &mut *ptr }; m3u8item.watched = true;
item.watched = true;
let mut args: Vec<&str> = vec![&m3u8item.link]; let mut args: Vec<&str> = vec![&m3u8item.link];
if launch_in_fullscreen { if launch_in_fullscreen {
args.push("--fs"); args.push("--fs");
@ -201,3 +190,11 @@ fn stream(m3u8item: &M3u8, launch_in_fullscreen: bool) {
.output() .output()
.expect("Could not listen for output"); .expect("Could not listen for output");
} }
/*
* I know that this is also frowned upon, but it is perfectly safe right here,
* even though the borrowchecker complains
*/
async fn refresh(parser: &Parser) {
unsafe { get_mut_ref(parser) }.forcefully_update().await;
}