2023-03-05 19:14:26 +01:00
|
|
|
#[allow(unused_imports)]
|
|
|
|
use crate::GetM3u8;
|
|
|
|
use crate::{
|
2023-03-05 20:02:26 +01:00
|
|
|
parser::{Parser, WatchedFind},
|
2023-03-05 19:51:21 +01:00
|
|
|
Configuration, OfflineParser, OnlineParser, Playlist, MAX_TRIES,
|
2023-03-05 19:14:26 +01:00
|
|
|
};
|
2023-03-05 20:26:52 +01:00
|
|
|
use std::{fs, rc::Rc};
|
2023-03-05 12:13:42 +01:00
|
|
|
|
2023-03-05 19:14:26 +01:00
|
|
|
type Error = String;
|
2023-03-05 12:13:42 +01:00
|
|
|
|
2023-03-05 19:14:26 +01:00
|
|
|
pub struct GrandMother {
|
2023-03-05 19:51:21 +01:00
|
|
|
pub parser: Box<dyn Parser>,
|
2023-03-05 19:14:26 +01:00
|
|
|
pub playlist: Option<Playlist>,
|
2023-03-05 20:26:52 +01:00
|
|
|
pub config: Rc<Configuration>,
|
2023-03-05 12:13:42 +01:00
|
|
|
}
|
|
|
|
|
2023-03-05 19:14:26 +01:00
|
|
|
impl GrandMother {
|
2023-03-05 20:26:52 +01:00
|
|
|
pub async fn new_online(config: Rc<Configuration>) -> Result<Self, Error> {
|
2023-03-05 12:13:42 +01:00
|
|
|
let playlist = Playlist::new(config.playlist_path.clone(), config.playlist_url.clone());
|
|
|
|
let seen_links = config.seen_links.iter().map(|x| x.as_str()).collect();
|
|
|
|
let playlist = playlist.await?;
|
|
|
|
let playlist_content = playlist.get_saved_or_download().await?;
|
2023-03-05 19:51:21 +01:00
|
|
|
let parser: Box<dyn Parser> =
|
|
|
|
Box::new(OnlineParser::new(&playlist_content, &seen_links).await);
|
2023-03-05 12:13:42 +01:00
|
|
|
|
|
|
|
Ok(Self {
|
|
|
|
parser,
|
2023-03-05 19:14:26 +01:00
|
|
|
playlist: Some(playlist),
|
2023-03-05 12:13:42 +01:00
|
|
|
config,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-03-05 20:26:52 +01:00
|
|
|
pub async fn promote_to_online(&mut self) -> Result<(), Error> {
|
|
|
|
let online_mother = GrandMother::new_online(self.config.clone()).await?;
|
|
|
|
(self.parser, self.playlist) = (online_mother.parser, online_mother.playlist);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_offline(config: Rc<Configuration>) -> Self {
|
2023-03-05 19:51:21 +01:00
|
|
|
let parser: Box<dyn Parser> = Box::new(OfflineParser::new(&config));
|
2023-03-05 19:14:26 +01:00
|
|
|
Self {
|
|
|
|
parser,
|
|
|
|
playlist: None,
|
|
|
|
config,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn refresh_dirty(&self) -> Result<(), Error> {
|
2023-03-05 12:13:42 +01:00
|
|
|
let ptr = self as *const Self as *mut Self;
|
2023-03-05 19:14:26 +01:00
|
|
|
unsafe { &mut *ptr }.refresh().await
|
2023-03-05 12:13:42 +01:00
|
|
|
}
|
|
|
|
|
2023-03-05 19:14:26 +01:00
|
|
|
pub async fn refresh(&mut self) -> Result<(), Error> {
|
2023-03-05 12:13:42 +01:00
|
|
|
let mut counter = 0;
|
|
|
|
let content = loop {
|
|
|
|
counter += 1;
|
2023-03-05 19:14:26 +01:00
|
|
|
let content = self
|
|
|
|
.playlist
|
|
|
|
.as_ref()
|
|
|
|
.ok_or_else(|| "Cannot refresh playlist in offlinemode")?
|
|
|
|
.download()
|
|
|
|
.await;
|
2023-03-05 12:13:42 +01:00
|
|
|
if counter > MAX_TRIES {
|
2023-03-05 19:14:26 +01:00
|
|
|
return Ok(());
|
2023-03-05 12:13:42 +01:00
|
|
|
}
|
|
|
|
if let Ok(content) = content {
|
|
|
|
break content;
|
|
|
|
}
|
|
|
|
println!("Retrying {}/{}", counter, MAX_TRIES);
|
|
|
|
};
|
|
|
|
|
2023-03-05 16:35:01 +01:00
|
|
|
let watched_links = self
|
|
|
|
.parser
|
|
|
|
.get_watched()
|
|
|
|
.iter()
|
|
|
|
.map(|x| x.link.as_str())
|
|
|
|
.collect();
|
2023-03-05 19:51:21 +01:00
|
|
|
self.parser = Box::new(OnlineParser::new(&content, &watched_links).await);
|
2023-03-05 19:14:26 +01:00
|
|
|
|
|
|
|
Ok(())
|
2023-03-05 12:13:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn save_watched(&self) {
|
|
|
|
let watched_items = self.parser.get_watched();
|
|
|
|
|
|
|
|
let resp = fs::write(
|
|
|
|
&self.config.seen_links_path,
|
|
|
|
serde_json::to_string(&watched_items).unwrap(),
|
|
|
|
);
|
|
|
|
|
|
|
|
if let Err(e) = resp {
|
|
|
|
eprintln!("Failed to write watched links {:?}", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|