tidying up
This commit is contained in:
parent
2419592f22
commit
19031035a1
@ -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)
|
||||||
}
|
}
|
||||||
|
10
src/lib.rs
10
src/lib.rs
@ -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
|
||||||
|
}
|
||||||
|
43
src/main.rs
43
src/main.rs
@ -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;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user