1
0
mirror of https://github.com/shimunn/aria2xspf.git synced 2023-11-17 09:27:54 +01:00
This commit is contained in:
shimunn 2019-03-16 18:51:03 +01:00
parent 5cc317cd61
commit 33dce1c40a

View File

@ -1,76 +1,89 @@
#[macro_use] #[macro_use]
extern crate derive_builder; extern crate derive_builder;
use std::io::{self, Write};
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io::{self, Write};
use std::io::{BufRead, BufReader}; use std::io::{BufRead, BufReader};
use xml::writer::{EventWriter, EmitterConfig, XmlEvent, Result as XResult}; use xml::writer::{EmitterConfig, EventWriter, Result as XResult, XmlEvent};
#[derive(Builder, Debug)] #[derive(Builder, Debug)]
struct Track { struct Track {
url: String, url: String,
title: String title: String,
} }
impl Track { impl Track {
fn new(url: String, title: String) -> Track {
fn new(url: String, title: String) -> Track { Track {
Track{ url: url,
url: url, title: title,
title: title }
} }
} fn write_xml<W: Write>(self, w: &mut EventWriter<W>) -> XResult<()> {
fn write_xml<W: Write>(self,w: &mut EventWriter<W>) -> XResult<()> { w.write(XmlEvent::start_element("track"))?;
let events: [XmlEvent; 8] = [ w.write(XmlEvent::start_element("location"))?;
XmlEvent::start_element("track".into()).into(), w.write(XmlEvent::characters(&self.url))?;
XmlEvent::start_element("location".into()).into(), w.write(XmlEvent::end_element())?;
XmlEvent::characters(&self.url).into(), w.write(XmlEvent::start_element("title"))?;
XmlEvent::end_element().into(), w.write(XmlEvent::characters(&self.title))?;
XmlEvent::start_element("title".into()).into(), w.write(XmlEvent::end_element())?;
XmlEvent::characters(&self.title).into(), w.write(XmlEvent::end_element())
XmlEvent::end_element().into(), }
XmlEvent::end_element().into()
];
for event in &events {
w.write(event.into()).into()?;
}
Ok(())
}
} }
fn main() { fn main() {
let file = File::open("VIDs").expect("Failed to open file!"); let file = File::open("VIDs").expect("Failed to open file!");
let mut out = File::create("VIDs.xspf").unwrap(); let mut out = File::create("VIDs.xspf").unwrap();
let mut writer = EmitterConfig::new().perform_indent(true).create_writer(&mut out); let mut writer = EmitterConfig::new()
convert(tracks(BufReader::new(file).lines().map(|line| line.expect("Failed to read line"))), &mut writer).expect("Failed to parse"); .perform_indent(true)
.create_writer(&mut out);
convert(
tracks(
BufReader::new(file)
.lines()
.map(|line| line.expect("Failed to read line")),
),
&mut writer,
)
.expect("Failed to parse");
} }
fn convert<I: Iterator<Item=Track>, W: Write>(tracks: I,w: &mut EventWriter<W>) -> XResult<()> { fn convert<I: Iterator<Item = Track>, W: Write>(tracks: I, w: &mut EventWriter<W>) -> XResult<()> {
w.write(XmlEvent::start_element("playlist".into()).ns("", "http://xspf.org/ns/0/").ns("vlc", "http://www.videolan.org/vlc/playlist/ns/0/")).into()?; w.write(
w.write(XmlEvent::start_element("trackList".into())).into()?; XmlEvent::start_element("playlist")
for track in tracks { .ns("", "http://xspf.org/ns/0/")
track.write_xml(w)?; .ns("vlc", "http://www.videolan.org/vlc/playlist/ns/0/"),
} )?;
w.write(XmlEvent::end_element().into()).into()?; w.write(XmlEvent::start_element("trackList"))?;
w.write(XmlEvent::end_element().into()).into()? for track in tracks {
track.write_xml(w)?;
}
w.write(XmlEvent::end_element())?;
w.write(XmlEvent::end_element())
} }
fn tracks<'a, I: Iterator<Item=String> + 'a>(aria: I) -> Box<Iterator<Item=Track> + 'a> { fn tracks<'a, I: Iterator<Item = String> + 'a>(aria: I) -> Box<Iterator<Item = Track> + 'a> {
let tracks = aria.scan(TrackBuilder::default(), |mut builder, line| { let tracks = aria
if !builder.url.is_some() { .scan(TrackBuilder::default(), |mut builder, line| {
builder.url(line); if !builder.url.is_some() {
} else { builder.url(line);
if line.starts_with("\t") { } else {
builder.title(line.chars().skip_while(|c| c != &'=').skip(1).collect::<String>()); if line.starts_with("\t") {
let track = Some(builder.build().unwrap()); builder.title(
*builder = TrackBuilder::default(); line.chars()
return Some(track); .skip_while(|c| c != &'=')
} .skip(1)
} .collect::<String>(),
Some(None) );
}).filter_map(|track| track); let track = Some(builder.build().unwrap());
Box::new(tracks) *builder = TrackBuilder::default();
return Some(track);
}
}
Some(None)
})
.filter_map(|track| track);
Box::new(tracks)
} }