start
This commit is contained in:
		
							
								
								
									
										157
									
								
								src/config.rs
									
									
									
									
									
								
							
							
						
						
									
										157
									
								
								src/config.rs
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
				
			|||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    fs::{self, File},
 | 
					    fs::{self, File},
 | 
				
			||||||
    io::{self, BufReader},
 | 
					    io::{self, BufReader},
 | 
				
			||||||
    ops::Deref,
 | 
					    ops::{Deref, DerefMut},
 | 
				
			||||||
    path::{Path, PathBuf},
 | 
					    path::{Path, PathBuf},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -9,7 +9,9 @@ use directories::ProjectDirs;
 | 
				
			|||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
use serde_json;
 | 
					use serde_json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{download_with_progress, get_mut_ref, m3u8::DataEntry, Readline};
 | 
					use crate::{
 | 
				
			||||||
 | 
					    download_with_progress, downloader::DualWriter, get_mut_ref, m3u8::DataEntry, M3u8, Readline,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const JSON_CONFIG_FILENAME: &'static str = "config.json";
 | 
					const JSON_CONFIG_FILENAME: &'static str = "config.json";
 | 
				
			||||||
const APP_IDENTIFIER: [&'static str; 3] = ["com", "billenius", "ilovetv"];
 | 
					const APP_IDENTIFIER: [&'static str; 3] = ["com", "billenius", "ilovetv"];
 | 
				
			||||||
@@ -154,65 +156,6 @@ impl Configuration {
 | 
				
			|||||||
        serde_json::from_reader(reader).ok()
 | 
					        serde_json::from_reader(reader).ok()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn should_update_playlist(&self) -> bool {
 | 
					 | 
				
			||||||
        fs::metadata(&self.playlist_path)
 | 
					 | 
				
			||||||
            .and_then(|metadata| {
 | 
					 | 
				
			||||||
                Ok({
 | 
					 | 
				
			||||||
                    let seconds = metadata.modified()?;
 | 
					 | 
				
			||||||
                    seconds
 | 
					 | 
				
			||||||
                        .elapsed()
 | 
					 | 
				
			||||||
                        .expect("Failed to get systemtime")
 | 
					 | 
				
			||||||
                        .as_secs()
 | 
					 | 
				
			||||||
                        > 60 * 60 * 24 * 3
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
            .map_or_else(
 | 
					 | 
				
			||||||
                |_| {
 | 
					 | 
				
			||||||
                    println!("Could not find playlist-file, Downloading a new one");
 | 
					 | 
				
			||||||
                    false
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                |x| x,
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    pub async fn get_playlist(&self) -> Result<String, String> {
 | 
					 | 
				
			||||||
        let content = if let Some(content) = self.get_saved_playlist() {
 | 
					 | 
				
			||||||
            content
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            let downloaded = self.download_playlist().await?;
 | 
					 | 
				
			||||||
            if let Err(e) = fs::write(&self.playlist_path, &downloaded) {
 | 
					 | 
				
			||||||
                println!(
 | 
					 | 
				
			||||||
                    "Failed to save downloaded playlist to file, {:?}, path: '{}'",
 | 
					 | 
				
			||||||
                    e,
 | 
					 | 
				
			||||||
                    &self.playlist_path.as_os_str().to_str().unwrap()
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            downloaded
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Ok(content)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn get_saved_playlist(&self) -> Option<String> {
 | 
					 | 
				
			||||||
        if !self.should_update_playlist() {
 | 
					 | 
				
			||||||
            return fs::read_to_string(&self.playlist_path).ok();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        None
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pub async fn download_playlist(&self) -> Result<String, String> {
 | 
					 | 
				
			||||||
        let mut counter: u8 = 0;
 | 
					 | 
				
			||||||
        loop {
 | 
					 | 
				
			||||||
            counter += 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if let Ok(content) = self.just_download().await {
 | 
					 | 
				
			||||||
                break Ok(content);
 | 
					 | 
				
			||||||
            } else if counter > MAX_TRIES {
 | 
					 | 
				
			||||||
                break Err("Failed to download playlist".to_owned());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            println!("Retrying {}/{}", counter + 1, MAX_TRIES);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async fn just_download(&self) -> Result<String, String> {
 | 
					    async fn just_download(&self) -> Result<String, String> {
 | 
				
			||||||
        download_with_progress(&self.playlist_url, None)
 | 
					        download_with_progress(&self.playlist_url, None)
 | 
				
			||||||
            .await?
 | 
					            .await?
 | 
				
			||||||
@@ -232,3 +175,95 @@ impl Deref for Configuration {
 | 
				
			|||||||
        &self.conf
 | 
					        &self.conf
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Playlist {
 | 
				
			||||||
 | 
					    pub entries: Vec<M3u8>,
 | 
				
			||||||
 | 
					    path_to_playlist: PathBuf,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Playlist {
 | 
				
			||||||
 | 
					    pub fn new(path_to_playlist: PathBuf) -> Self {
 | 
				
			||||||
 | 
					        todo!()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn write() -> Result<(), io::Error> {
 | 
				
			||||||
 | 
					        todo!()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn get_saved_playlist(path: &Path) -> Option<String> {
 | 
				
			||||||
 | 
					        if !Self::should_update_playlist(path) {
 | 
				
			||||||
 | 
					            return fs::read_to_string(path).ok();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        None
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn should_update_playlist(path: &Path) -> bool {
 | 
				
			||||||
 | 
					        fs::metadata(path)
 | 
				
			||||||
 | 
					            .and_then(|metadata| {
 | 
				
			||||||
 | 
					                Ok({
 | 
				
			||||||
 | 
					                    let seconds = metadata.modified()?;
 | 
				
			||||||
 | 
					                    seconds
 | 
				
			||||||
 | 
					                        .elapsed()
 | 
				
			||||||
 | 
					                        .expect("Failed to get systemtime")
 | 
				
			||||||
 | 
					                        .as_secs()
 | 
				
			||||||
 | 
					                        > 60 * 60 * 24 * 3
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .map_or_else(
 | 
				
			||||||
 | 
					                |_| {
 | 
				
			||||||
 | 
					                    println!("Could not find playlist-file, Downloading a new one");
 | 
				
			||||||
 | 
					                    false
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                |x| x,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn get_playlist(&self, url: &str, path: &Path) -> Result<String, String> {
 | 
				
			||||||
 | 
					        let content = if let Some(content) = Self::get_saved_playlist(path) {
 | 
				
			||||||
 | 
					            content
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            let downloaded = Self::download_playlist(url).await?;
 | 
				
			||||||
 | 
					            if let Err(e) = fs::write(path, &downloaded) {
 | 
				
			||||||
 | 
					                println!(
 | 
				
			||||||
 | 
					                    "Failed to save downloaded playlist to file, {:?}, path: '{}'",
 | 
				
			||||||
 | 
					                    e,
 | 
				
			||||||
 | 
					                    path.as_os_str().to_str().unwrap()
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            downloaded
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(content)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn download_playlist(url: &str) -> Result<String, String> {
 | 
				
			||||||
 | 
					        let mut counter: u8 = 0;
 | 
				
			||||||
 | 
					        loop {
 | 
				
			||||||
 | 
					            counter += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let downloaded = download_with_progress(url, None)
 | 
				
			||||||
 | 
					                .await
 | 
				
			||||||
 | 
					                .and_then(DualWriter::get_string);
 | 
				
			||||||
 | 
					            if let Ok(content) = downloaded {
 | 
				
			||||||
 | 
					                break Ok(content);
 | 
				
			||||||
 | 
					            } else if counter > MAX_TRIES {
 | 
				
			||||||
 | 
					                break Err("Failed to download playlist".to_owned());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            println!("Retrying {}/{}", counter + 1, MAX_TRIES);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Deref for Playlist {
 | 
				
			||||||
 | 
					    type Target = Vec<M3u8>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn deref(&self) -> &Self::Target {
 | 
				
			||||||
 | 
					        &self.entries
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl DerefMut for Playlist {
 | 
				
			||||||
 | 
					    fn deref_mut(&mut self) -> &mut Self::Target {
 | 
				
			||||||
 | 
					        &mut self.entries
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user