Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed errors when deleting an episode that is not anymore available anymore #1057

Merged
merged 1 commit into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/constants/inner_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ pub const DATABASE_URL_DEFAULT_SQLITE: &str = "sqlite://./db/podcast.db";
pub const CSS: &str = "css";
pub const JS: &str = "javascript";

pub const MAX_FILE_TREE_DEPTH: i32 = 4;

pub const COMMON_USER_AGENT: &str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 \
(KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36";
Expand Down
97 changes: 46 additions & 51 deletions src/service/file_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,22 @@ use std::io::{Error, Write};
use std::path::Path;
use std::str::FromStr;

use crate::constants::inner_constants::MAX_FILE_TREE_DEPTH;
use crate::models::podcast_episode::PodcastEpisode;
use regex::Regex;
use rss::Channel;
use tokio::task::spawn_blocking;
use crate::adapters::persistence::dbconfig::db::get_connection;
use crate::controllers::settings_controller::ReplacementStrategy;
use crate::models::misc_models::PodcastInsertModel;
use crate::models::podcast_episode::PodcastEpisode;
use crate::models::podcast_settings::PodcastSetting;
use crate::models::settings::Setting;
use crate::service::path_service::PathService;
use crate::service::settings_service::SettingsService;
use crate::utils::error::{map_io_error, CustomError};
use crate::utils::file_extension_determination::{determine_file_extension, FileType};
use crate::utils::file_name_replacement::{Options, Sanitizer};
use crate::utils::rss_feed_parser::RSSFeedParser;
use crate::DBType as DbConnection;
use crate::models::podcast_settings::PodcastSetting;
use crate::utils::file_name_replacement::{Options, Sanitizer};

use regex::Regex;
use rss::Channel;
use tokio::task::spawn_blocking;

#[derive(Clone)]
pub struct FileService {
Expand Down Expand Up @@ -130,41 +128,32 @@ impl FileService {
PodcastEpisode::update_podcast_image(podcast_id, &file_path.1).unwrap();
}

pub fn cleanup_old_episode(episode: PodcastEpisode) -> Result<(), CustomError> {
pub fn cleanup_old_episode(episode: &PodcastEpisode) -> Result<(), CustomError> {
log::info!("Cleaning up old episode: {}", episode.episode_id);
let splitted_url = episode.url.split('/').collect::<Vec<&str>>();
match splitted_url.len() as i32 == MAX_FILE_TREE_DEPTH {
true => {
let path = move_one_path_up(&episode.file_image_path.unwrap());
std::fs::remove_dir_all(&path).map_err(|v| map_io_error(v, Some(path)))

fn check_if_file_exists(file_path: &str) -> bool {
std::fs::exists(file_path).unwrap()
}
if let Some(episode_path) = episode.file_episode_path.clone() {
if check_if_file_exists(&episode_path) {
std::fs::remove_file(episode_path)
.map_err(|e| map_io_error(e, episode.file_episode_path.clone()))?;
}
false => {
if episode.file_episode_path.is_some() {
std::fs::remove_file(episode.file_episode_path.clone().unwrap())
.map_err(|e| map_io_error(e, episode.file_episode_path))?;
}
if episode.file_image_path.is_some() {
std::fs::remove_file(episode.file_image_path.clone().unwrap())
.map_err(|e| map_io_error(e, episode.file_image_path))?;
}
Ok(())
}
if let Some(image_path) = episode.file_image_path.clone() {
if check_if_file_exists(&image_path) {
std::fs::remove_file(image_path)
.map_err(|e| map_io_error(e, episode.file_image_path.clone()))?;
}
}
Ok(())
}

pub fn delete_podcast_files(podcast_dir: &str) {
std::fs::remove_dir_all(podcast_dir).expect("Error deleting podcast directory");
}
}

fn move_one_path_up(path: &str) -> String {
const SEPARATOR: &str = "/";
let mut split = path.split(SEPARATOR).collect::<Vec<&str>>();
split.pop();

split.join(SEPARATOR)
}

pub async fn prepare_podcast_title_to_directory(
podcast: &PodcastInsertModel,
channel: Option<Channel>,
Expand All @@ -186,7 +175,7 @@ pub async fn prepare_podcast_title_to_directory(
}
};

perform_podcast_variable_replacement(retrieved_settings, podcast.clone(),opt_podcast_settings)
perform_podcast_variable_replacement(retrieved_settings, podcast.clone(), opt_podcast_settings)
}

fn replace_date_of_str(date: &str) -> String {
Expand All @@ -202,11 +191,15 @@ fn replace_date_of_str(date: &str) -> String {
pub fn perform_podcast_variable_replacement(
retrieved_settings: Setting,
podcast: crate::utils::rss_feed_parser::PodcastParsed,
podcast_setting: Option<PodcastSetting>
podcast_setting: Option<PodcastSetting>,
) -> Result<String, CustomError> {
let sanitizer = Sanitizer::new(None);
let escaped_podcast_title = perform_replacement(&podcast.title, retrieved_settings.clone(), podcast_setting.clone())
.replace(|c: char| !c.is_ascii(), "");
let escaped_podcast_title = perform_replacement(
&podcast.title,
retrieved_settings.clone(),
podcast_setting.clone(),
)
.replace(|c: char| !c.is_ascii(), "");
let podcast_format;

if podcast_setting.is_none() {
Expand All @@ -221,9 +214,7 @@ pub fn perform_podcast_variable_replacement(
podcast_format = retrieved_settings.podcast_format.clone();
}

if podcast_format.is_empty()
|| podcast_format.trim() == "{}"
{
if podcast_format.is_empty() || podcast_format.trim() == "{}" {
return Ok(sanitizer.sanitize(podcast.title));
}

Expand Down Expand Up @@ -284,9 +275,12 @@ pub fn perform_episode_variable_replacement(
podcast_episode: PodcastEpisode,
podcast_settings: Option<PodcastSetting>,
) -> Result<String, CustomError> {
let escaped_episode_title =
perform_replacement(&podcast_episode.name, retrieved_settings.clone(), podcast_settings.clone())
.replace(|c: char| !c.is_ascii(), "");
let escaped_episode_title = perform_replacement(
&podcast_episode.name,
retrieved_settings.clone(),
podcast_settings.clone(),
)
.replace(|c: char| !c.is_ascii(), "");
let episode_format;

if podcast_settings.is_none() {
Expand All @@ -301,9 +295,7 @@ pub fn perform_episode_variable_replacement(
episode_format = retrieved_settings.episode_format.clone();
}


if episode_format.is_empty() || episode_format.trim() == "{}"
{
if episode_format.is_empty() || episode_format.trim() == "{}" {
return Ok(escaped_episode_title);
}

Expand Down Expand Up @@ -344,8 +336,11 @@ pub fn perform_episode_variable_replacement(
}
}

fn perform_replacement(title: &str, retrieved_settings: Setting, podcast_settings: Option<PodcastSetting>) ->
String {
fn perform_replacement(
title: &str,
retrieved_settings: Setting,
podcast_settings: Option<PodcastSetting>,
) -> String {
let mut final_string: String = title.to_string();
let replacement_strategy;
if podcast_settings.is_none() {
Expand All @@ -369,11 +364,11 @@ fn perform_replacement(title: &str, retrieved_settings: Setting, podcast_setting
ReplacementStrategy::Remove => {
let sanitizer = Sanitizer::new(Some(Options::default_with_replacement("")));
final_string = sanitizer.sanitize(&final_string);
},
}
ReplacementStrategy::ReplaceWithDash => {
let sanitizer = Sanitizer::new(Some(Options::default_with_replacement("-")));
final_string = sanitizer.sanitize(&final_string);
},
}
}
final_string
}
Expand Down Expand Up @@ -584,7 +579,7 @@ mod tests {
local_image_url: "".to_string(),
download_time: None,
deleted: false,
episode_numbering_processed: false
episode_numbering_processed: false,
};

let result = perform_episode_variable_replacement(settings, podcast_episode, None);
Expand Down Expand Up @@ -626,7 +621,7 @@ mod tests {
local_image_url: "".to_string(),
download_time: None,
deleted: false,
episode_numbering_processed:false
episode_numbering_processed: false,
};

let result = perform_episode_variable_replacement(settings, podcast_episode, None);
Expand Down
18 changes: 13 additions & 5 deletions src/service/podcast_episode_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ impl PodcastEpisodeService {

log::info!("Cleaning up {} old episodes", old_podcast_episodes.len());
for old_podcast_episode in old_podcast_episodes {
let res = FileService::cleanup_old_episode(old_podcast_episode.clone());
let res = FileService::cleanup_old_episode(&old_podcast_episode);

match res {
Ok(_) => {
Expand Down Expand Up @@ -572,10 +572,18 @@ impl PodcastEpisodeService {
if episode.is_none() {
return Err(CustomError::NotFound);
}
FileService::cleanup_old_episode(episode.clone().unwrap())?;
PodcastEpisode::update_download_status_of_episode(episode.clone().unwrap().id);
PodcastEpisode::update_deleted(episode_id, true)?;
Ok(episode.unwrap())

match episode {
Some(episode)=>{
FileService::cleanup_old_episode(&episode)?;
PodcastEpisode::update_download_status_of_episode(episode.id);
PodcastEpisode::update_deleted(episode_id, true)?;
Ok(episode)
}
None=>{
Err(CustomError::NotFound)
}
}
}

pub fn get_track_number_for_episode(
Expand Down
Loading