Skip to content

Commit 6da560b

Browse files
committed
fix: fix passing multiple audio files as args
imagine the arguments `./encore something.png something.mp3` this won't work, because encore originally intreprets something.png as a **non-audio** file, so it tries to parse it as a playlist, and dies because &str/String expects to be utf8. whereas... `./encore something.mp3 something.png` works right, because encore treats it correctly (audio files instead of playlist) this commit fixes that behaviour and makes it right, but due to how it was written originally, it had to be refactored. its probably not the best way to fix it, or rewrite it in this case, but it works.
1 parent 7adb481 commit 6da560b

File tree

1 file changed

+56
-25
lines changed

1 file changed

+56
-25
lines changed

src/main.rs

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ fn parse_playlist(file: BufReader<File>) -> Result<(), Box<dyn std::error::Error
2525
for line in file.lines() {
2626
let mut line = match line {
2727
Ok(k) => k,
28-
Err(err) => return Err(format!("argv[1] should be a media file or Encore-compatable playlist.\n{err}").into()),
28+
Err(ref _err) => {
29+
// we aren't returning errors here because the playlist may have files whose paths
30+
// arent valid or cannot be read from
31+
continue;
32+
}
2933
};
3034
if line.starts_with("//") {
3135
continue; // its a comment; skip
@@ -35,11 +39,34 @@ fn parse_playlist(file: BufReader<File>) -> Result<(), Box<dyn std::error::Error
3539
lines.push(line); // file exists, therefore, push it onto the playlist
3640
}
3741
}
38-
lines.shrink_to_fit();
3942

4043
Ok(())
4144
}
4245

46+
// TODO: this can probably be done better with trait bounds or something
47+
fn parse_playlist_vec(file: &Vec<String>) -> Result<encore::RenderMode, Box<dyn std::error::Error>> {
48+
let mut ret = encore::RenderMode::Full;
49+
let mut lines = PLAYLIST.write().unwrap();
50+
if file.len() > 2 {
51+
for s in file.iter()
52+
.skip(1) // the first index is encore itself
53+
.by_ref() // then actually iterate through it
54+
{
55+
let mut f = BufReader::new(File::open(s)?);
56+
if *file_format::check_file(&mut f)? != encore::FileFormat::Audio {
57+
eprintln!("File {s} suspected to not be an audio file, or at least not one supported by Encore. Skipping.");
58+
continue;
59+
}
60+
lines.push(s.to_owned());
61+
}
62+
} else {
63+
ret = encore::RenderMode::Safe; // only one song, so do minimal
64+
lines.push(file[1].to_string());
65+
}
66+
67+
Ok(ret)
68+
}
69+
4370
fn quit_with(e: &str, s: &str) -> Result<std::convert::Infallible, Box<dyn std::error::Error>> {
4471
eprintln!("{e}");
4572
Err(s.into())
@@ -60,33 +87,37 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
6087
quit_with("argv[1] should be a media file or Encore-compatable playlist.", "argv[1] not supplied")?;
6188
}
6289

63-
let file = &args[1];
64-
let mut reader = BufReader::new(File::open(file)?);
65-
let fmt = file_format::check_file(&mut reader)?;
6690
let mut render_requested_mode = encore::RenderMode::Full;
6791

68-
match fmt {
69-
encore::FileFormat::Other => {
70-
parse_playlist(reader)?;
71-
if PLAYLIST.read().unwrap().len() == 0 {
72-
quit_with("no songs in playlist array; are all of the paths valid?", "playlist file has zero length")?;
92+
if args.len() == 2 {
93+
let mut first_arg = BufReader::new(File::open(&args[1])?);
94+
match file_format::check_file(&mut first_arg).unwrap() {
95+
encore::FileFormat::Audio => {
96+
render_requested_mode = parse_playlist_vec(&args).unwrap();
7397
}
74-
},
75-
encore::FileFormat::Audio => {
76-
let mut lines = PLAYLIST.write().unwrap();
77-
if args.len() > 2 {
78-
for s in args.iter()
79-
.skip(1) // the first index is encore itself
80-
.by_ref() // then actually iterate through it
81-
{
82-
lines.push(s.to_owned());
83-
}
84-
} else {
85-
render_requested_mode = encore::RenderMode::Safe; // only one song, so do minimal
86-
lines.push(file.to_string());
98+
encore::FileFormat::Other => {
99+
parse_playlist(first_arg).unwrap();
87100
}
88-
},
89-
};
101+
}
102+
} else {
103+
render_requested_mode = parse_playlist_vec(&args).unwrap();
104+
}
105+
106+
// verify all files are valid, and if not, remove them
107+
// this code can be slow, but no way around it
108+
let pl = PLAYLIST.read().unwrap().clone(); // clone to avoid deadlock later on (we'll acquire a write lock later)
109+
for (i, s) in pl.into_iter().enumerate() {
110+
let mut p = PLAYLIST.write().unwrap();
111+
let buf = &mut BufReader::new(File::open(&s)?);
112+
if *file_format::check_file(buf)? != encore::FileFormat::Audio {
113+
eprintln!("Removing `{s}` from playlist: not audio file");
114+
p.remove(i);
115+
}
116+
}
117+
118+
if PLAYLIST.read().unwrap().len() == 0 {
119+
quit_with("no songs in playlist array; are all of the paths valid?", "playlist file has zero length")?;
120+
}
90121

91122
let (mtx, mrx) = channel();
92123
let mtx = Arc::new(mtx);

0 commit comments

Comments
 (0)