deleting and not generating empty unlistened playlists
This commit is contained in:
@@ -11,6 +11,9 @@ pub(crate) const IPOD_PODCASTS_DIR: &str = "Podcasts";
|
||||
pub(crate) const LISTENED_PLAYLIST_PATH: &str = "[PC Meta] [Listened].m3u";
|
||||
pub(crate) const MASTER_PLAYLIST_PATH: &str = "[PC Meta] [Master Feed].m3u";
|
||||
|
||||
pub(crate) const PLAYLIST_PREFIX: &str = "[PC]";
|
||||
pub(crate) const UNLISTENED_SUFFIX: &str = "(unlistened)";
|
||||
|
||||
pub(crate) fn podcast_folder(
|
||||
root: &path::Path,
|
||||
alias: &str,
|
||||
|
||||
@@ -80,6 +80,9 @@ fn main() -> anyhow::Result<()> {
|
||||
spec.write_to(&spec_file)?;
|
||||
}
|
||||
Command::Playlist { podcast } => {
|
||||
// Empty playlist folder.
|
||||
// playlist::empty_playlists(root)?;
|
||||
|
||||
if let Some(alias) = podcast {
|
||||
playlist::generate_podcast_m3u(alias.as_str(), root, false)?;
|
||||
playlist::generate_podcast_m3u(alias.as_str(), root, true)?;
|
||||
@@ -106,6 +109,9 @@ fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// Empty playlist folder.
|
||||
// playlist::empty_playlists(root)?;
|
||||
|
||||
// Generate updated playlist files
|
||||
for (alias, _) in &config.podcasts {
|
||||
playlist::generate_podcast_m3u(alias.as_str(), root, true)?;
|
||||
|
||||
@@ -29,6 +29,10 @@ impl<'a> Playlist<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
self.files.is_empty()
|
||||
}
|
||||
|
||||
/// Writes the playlist file based on the specified filename.
|
||||
///
|
||||
/// Output boolean indicates if the playlist was written (if it was
|
||||
@@ -41,11 +45,21 @@ impl<'a> Playlist<'a> {
|
||||
let playlists_folder = self.root.join(folders::LOCAL_PLAYLISTS_DIR);
|
||||
if !playlists_folder.exists() {
|
||||
fs::create_dir(&playlists_folder)
|
||||
.context(format!("failed to create output directory for playlists"))?;
|
||||
.context("failed to create output directory for playlists")?;
|
||||
}
|
||||
let mut path = playlists_folder.join(sanitise(name));
|
||||
path.set_extension("m3u");
|
||||
|
||||
// If the playlist is empty, then don't write it,
|
||||
// and delete the existing one if it exists.
|
||||
if self.is_empty() {
|
||||
if path.exists() {
|
||||
fs::remove_file(&path)
|
||||
.context("failed to remove existing playlist to empty")?;
|
||||
}
|
||||
return Ok(false)
|
||||
}
|
||||
|
||||
let mut output = io::BufWriter::new(Vec::new());
|
||||
let mut writer = m3u::Writer::new(&mut output);
|
||||
let entries =
|
||||
@@ -136,6 +150,20 @@ pub(crate) fn generate_master_m3u(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Empties the playlist output folder.
|
||||
pub(crate) fn empty_playlists(
|
||||
root: &path::Path,
|
||||
) -> anyhow::Result<()> {
|
||||
let playlists_folder = root.join(folders::LOCAL_PLAYLISTS_DIR);
|
||||
if playlists_folder.exists() {
|
||||
fs::remove_dir_all(&playlists_folder)
|
||||
.context("failed to remove output directory for playlists")?;
|
||||
}
|
||||
fs::create_dir(&playlists_folder)
|
||||
.context("failed to create output directory for playlists")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn generate_podcast_m3u(
|
||||
alias: &str,
|
||||
@@ -170,9 +198,9 @@ pub(crate) fn generate_podcast_m3u(
|
||||
}
|
||||
|
||||
let written = if unlistened_only {
|
||||
playlist.write_as(&format!("[PC] {} (unlistened)", alias), false)
|
||||
playlist.write_as(&format!("{} {} {}", folders::PLAYLIST_PREFIX, alias, folders::UNLISTENED_SUFFIX), false)
|
||||
} else {
|
||||
playlist.write_as(&format!("[PC] {}", alias), false)
|
||||
playlist.write_as(&format!("{} {}", folders::PLAYLIST_PREFIX, alias), false)
|
||||
}?;
|
||||
|
||||
if written {
|
||||
|
||||
25
src/sync.rs
25
src/sync.rs
@@ -175,15 +175,40 @@ pub(crate) fn sync(
|
||||
anyhow::bail!("specified target directory does not contain a folder {:?}", folders::LOCAL_PLAYLISTS_DIR);
|
||||
}
|
||||
|
||||
// This is a bit of a hack, but we use the list of acknowledged
|
||||
// files in the target to recognise which unlistened playlists
|
||||
// should be deleted (because they don't exist in the local directory).
|
||||
// This won't delete any other extra podcasts, and is just a temporary
|
||||
// fix to make sure empty unlistened playlists don't exist.
|
||||
let mut acknowledged = BTreeSet::new();
|
||||
for source in fs::read_dir(root.join(folders::LOCAL_PLAYLISTS_DIR))? {
|
||||
let source = source?.path();
|
||||
let target = target_dir
|
||||
.join(folders::LOCAL_PLAYLISTS_DIR)
|
||||
.join(source.file_name().unwrap());
|
||||
|
||||
acknowledged.insert(target.clone());
|
||||
|
||||
if !target.exists() || fs::metadata(&target)?.modified()? < fs::metadata(&source)?.modified()? {
|
||||
println!("[info] copying playlist {:?}.", source.file_name().unwrap());
|
||||
fs::copy(source, target)?;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Here we delete the excess unlistened playlists (if the don't exist
|
||||
// in local directory, and thus correspond to empty playlists).
|
||||
//
|
||||
// This could very easily be edited to remove other excess playlists.
|
||||
for target in fs::read_dir(target_dir.join(folders::LOCAL_PLAYLISTS_DIR))? {
|
||||
let target = target?.path();
|
||||
let file_name = target.file_stem().unwrap();
|
||||
let file_name = file_name.to_str().unwrap();
|
||||
|
||||
if file_name.starts_with(folders::PLAYLIST_PREFIX)
|
||||
&& file_name.ends_with(folders::UNLISTENED_SUFFIX)
|
||||
&& !acknowledged.contains(&target) {
|
||||
fs::remove_file(&target)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user