57DU4YHARHICJPWTTHSBB5O7MAW7GJVJUMVEREGVWEMHCGI7JMLQC KHBYSOY7O3OGZLSIYZL6XRYHPNESD7WG2IAT7JT7HBTTCZVW4WJAC ED7GAY6WJJ6Y3476KCKQULZ4XF73XBREX6FLX6URUAWCL5KDTBBQC XIHPYOWDLQY2MVMVUQPH23O3TBALRG4G2CHSLWSCAYMY5NVJ32WQC DP6ASS5FJGSZUG2B4SQOKZVHFAVZLEHFVEWBNFG3BHMC6FZAJNHQC MQKD76RYJOC3SJ4EPKQRQFV7A2BRJAHAI4VMMLR4EKV4B3EV5YTQC UIMZBURR7KOWSREO4GDH5C2LZDUTEZBKQNYWBYSFGUTRYJ4GKSNQC LG3NDQDEZ65QP564QKTTYC3XI4ZN3NVW4B5T36QJEBHMJAEH4VEAC JYSIHNS67XTGAR4HN7ZHWFMGGYSK5IY6J6EHO4YUZOR7UMMWAORQC 476KTQSS5NXVCTVLVZQRGSYD5OAFBYG75VTSWBN26Q45RSMRT5YQC HTHQWZRRS5N2J3VMS4VFT3MMOBA4MHVTO6REWCHU2RJIDSN3HTSQC AFGKYLKUV6QBTL7JYDNOUCO2BVUR6CUB5MAKA3V3C76XGCWJULQAC 3YR56Y65UIAL3J7PUXWVJMOOHYZYDIX4V54OT2TJPZ25WQ6MXHCQC 5JMYBRF3UYX4LFH7JK6S4BEDKRVKDFIL4YKTCWKMKP4TMNNGQFKQC NE63ERXN7OUYSQ4PGPIQIIKEYD7OAOWXXSGMTORD6RJNUZHRLVJAC HXMFYFMLDAJOOUUALCZRUJJFOIWUFK7CGO5MNSJVO2XMR63KOTAAC IMRHIIAUQDSKU4D6YONK67D6GH7ZLLMMB5S2HRZT76SYNJ7M2RSQC 52CTWUQP2WCBMYNGOIOLOVUYWXF3YOJAPJY3WIHIFLIQD2WHIDFQC O3VZ5J3LIYD3KBZLZA6HOJI7MVOV5DEODDPCPOMIBTPCO3CZW4YQC GE7XXDPC73SUY6I6F3X6I4QFQO2BCPHD4MZALYOWG7H7SRE5XAFQC BSPWOOHZMN3RAOHGJ2A3XKUOUCFFAOXS7YR67E3AARPPPIA5YPDAC 76TBVFPIFU3LSMXY5NAHZBH6HRJLSLK43PGOPL6QQ2YYVBJ64QAQC EZMX4SYFEBYNJVQETRVAYONU5MIMQYTTSA5DRMTQET5B7CL6CI6AC 37X6ZKCCWP4OPXA7QMA2VG2IZHSXS6TQFTKMONU35NLMWKA47JUQC 5FEMSWRS6SMVKBJAV4IYJLEJ2CML6QNZM75UGQFIIMAR5FBAACXAC ADXMUSFXOKBPCHW4XS3T4KLWMPGQPYDMZW6YFFSHZPAQKEGIKCBQC MQKOX2CQ7AON24UJC7RORAC7Y2UROROVG7BBKLVWURPXKY75JV5AC Y6BVNXQ747WQKVB4JO3AHYOMBWNNJNPC6SG2UUCCZRIIXDMXJYDQC J64KBLKALQ3HQCY4HJU5H6WBXTATS7TKBYNNUUSNJE7JLWLYO66QC use crate::utils::*;use std::fs;fn migrate_old_subscriptions() -> Result<()> {let path = get_podcast_dir()?;let mut old_path = path.clone();old_path.push(".subscriptions");if old_path.exists() {println!("Migrating old subscriptions file...");let new_path = get_sub_file()?;fs::rename(&old_path, &new_path)?;}Ok(())}pub fn migrate() -> Result<()> {migrate_old_subscriptions()}use anyhow::Result;
pub async fn update_subscription(client: &reqwest::Client, sub: &mut Subscription, config: Option<Config>) -> Result<()> {
pub async fn update_subscription(client: &reqwest::Client,index: usize,sub: &Subscription,config: Option<Config>,) -> Result<[usize; 2]> {
for c in futures::future::join_all(d_vec).await.iter() {if let Err(err) = c {println!("Error: {}", err);
let new_subscriptions = futures::future::join_all(d_vec).await;for c in &new_subscriptions {match c {Ok([index, new_ep_count]) => {state.subscriptions[*index].num_episodes = *new_ep_count;},Err(err) => {println!("Error: {}", err);}
command_handler::handle_matches(&VERSION, &client, &mut state, config, &mut app, &matches).await?;state.save()
// Instantiate the global state of the applicationlet mut state = State::new( VERSION, config).await?;command_handler::handle_matches(&VERSION, &mut state, config, &mut app, &matches).await?;let public_state: PublicState = state.into();public_state.save()?;Ok(())
pub struct PublicState {pub version: String,pub last_run_time: DateTime<Utc>,pub config: Config,pub subscriptions: Vec<Subscription>,}impl From<State> for PublicState {fn from(internal_state: State) -> Self {PublicState {version: internal_state.version,last_run_time: internal_state.last_run_time,config: internal_state.config,subscriptions: internal_state.subscriptions,}}}impl PublicState {pub fn save(&self) -> Result<()> {let mut path = config_path()?;path.set_extension("json.tmp");let file = File::create(&path)?;serde_json::to_writer(BufWriter::new(file), self)?;fs::rename(&path, config_path()?)?;Ok(())}}#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]struct ParseState {version: Option<String>,last_run_time: Option<DateTime<Utc>>,config: Option<Config>,subscriptions: Option<Vec<Subscription>>,}impl From<ParseState> for State {fn from(internal_state: ParseState) -> Self {State {version: internal_state.version.unwrap(),last_run_time: internal_state.last_run_time.unwrap_or_else(|| Utc::now()),config: internal_state.config.unwrap_or_else(|| Config::default()),subscriptions: internal_state.subscriptions.unwrap_or_else(|| vec![]),client: reqwest::Client::new(),}}}
pub async fn new(client: &reqwest::Client, version: &str) -> Result<State> {let path = get_sub_file()?;if path.exists() {let file = File::open(&path)?;let mut state: State = serde_json::from_reader(BufReader::new(&file))?;
pub async fn new(version: &str, config: Config) -> Result<State> {let config_path = config_path()?;let legacy_subscription_path = get_sub_file()?;// TODO This moves legacy file into new location. Remove this.if legacy_subscription_path.exists() {std::fs::rename(&legacy_subscription_path, &config_path)?;}if config_path.exists() {let file = File::open(&config_path)?;// Read the file into an internal struct that allows optionally missing fieldslet parse_state: ParseState = serde_json::from_reader(BufReader::new(&file))?;// Convert to our public state that has sensible default for non-present fieldslet mut state: State = parse_state.into();// Override version to the version currently running
// Check if a day has passed (86400 seconds) since last launchif 86400< Utc::now().signed_duration_since(state.last_run_time).num_seconds()
// Check if a day has passed since last launchif 0 < Utc::now().signed_duration_since(state.last_run_time).num_days()
self.save()}pub fn save(&self) -> Result<()> {let mut path = get_sub_file()?;path.set_extension("json.tmp");let file = File::create(&path)?;serde_json::to_writer(BufWriter::new(file), self)?;fs::rename(&path, get_sub_file()?)?;