@@ -25,7 +25,11 @@ fn parse_playlist(file: BufReader<File>) -> Result<(), Box<dyn std::error::Error
25
25
for line in file. lines ( ) {
26
26
let mut line = match line {
27
27
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
+ }
29
33
} ;
30
34
if line. starts_with ( "//" ) {
31
35
continue ; // its a comment; skip
@@ -35,11 +39,34 @@ fn parse_playlist(file: BufReader<File>) -> Result<(), Box<dyn std::error::Error
35
39
lines. push ( line) ; // file exists, therefore, push it onto the playlist
36
40
}
37
41
}
38
- lines. shrink_to_fit ( ) ;
39
42
40
43
Ok ( ( ) )
41
44
}
42
45
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
+
43
70
fn quit_with ( e : & str , s : & str ) -> Result < std:: convert:: Infallible , Box < dyn std:: error:: Error > > {
44
71
eprintln ! ( "{e}" ) ;
45
72
Err ( s. into ( ) )
@@ -60,33 +87,37 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
60
87
quit_with ( "argv[1] should be a media file or Encore-compatable playlist." , "argv[1] not supplied" ) ?;
61
88
}
62
89
63
- let file = & args[ 1 ] ;
64
- let mut reader = BufReader :: new ( File :: open ( file) ?) ;
65
- let fmt = file_format:: check_file ( & mut reader) ?;
66
90
let mut render_requested_mode = encore:: RenderMode :: Full ;
67
91
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 ( ) ;
73
97
}
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 ( ) ;
87
100
}
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
+ }
90
121
91
122
let ( mtx, mrx) = channel ( ) ;
92
123
let mtx = Arc :: new ( mtx) ;
0 commit comments