mirror of
https://github.com/shimunn/aria2xspf.git
synced 2023-11-17 09:27:54 +01:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35b01ba152 | ||
|
|
51c1371f46 | ||
|
|
fe8a0f5d9f | ||
|
|
33dce1c40a |
42
.drone.yml
Normal file
42
.drone.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
image: rust:1.34.0
|
||||
environment:
|
||||
CARGO_HOME: /drone/.cargo
|
||||
commands:
|
||||
- cargo test
|
||||
- rustup component add rustfmt
|
||||
- cargo fmt -- --check
|
||||
- name: build_relase
|
||||
image: rust:1.34.0
|
||||
environment:
|
||||
CARGO_HOME: /drone/.cargo
|
||||
commands:
|
||||
- mkdir bin
|
||||
- export CARGO_INSTALL_ROOT=$PWD
|
||||
- rustup target add x86_64-unknown-linux-musl
|
||||
- cargo install --path . --target x86_64-unknown-linux-musl
|
||||
- mkdir dist
|
||||
- tar cvzf binary.tar.gz bin/*
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
- name: gitea_release
|
||||
image: plugins/gitea-release
|
||||
settings:
|
||||
api_key:
|
||||
from_secret: gitea_tkn
|
||||
base_url:
|
||||
from_secret: gitea_url
|
||||
files:
|
||||
- binary.tar.gz
|
||||
checksum:
|
||||
- md5
|
||||
- sha512
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
|
||||
4
README.md
Normal file
4
README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# WIP: aria2xspf
|
||||
|
||||
Will convert a file, that is formatted according to https://aria2.github.io/manual/en/html/aria2c.html#id2 into a VLC xspf Playlist
|
||||
|
||||
119
src/main.rs
119
src/main.rs
@@ -1,76 +1,89 @@
|
||||
#[macro_use]
|
||||
extern crate derive_builder;
|
||||
|
||||
use std::io::{self, Write};
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
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)]
|
||||
struct Track {
|
||||
url: String,
|
||||
title: String
|
||||
url: String,
|
||||
title: String,
|
||||
}
|
||||
|
||||
impl Track {
|
||||
|
||||
fn new(url: String, title: String) -> Track {
|
||||
Track{
|
||||
url: url,
|
||||
title: title
|
||||
}
|
||||
}
|
||||
fn write_xml<W: Write>(self,w: &mut EventWriter<W>) -> XResult<()> {
|
||||
let events: [XmlEvent; 8] = [
|
||||
XmlEvent::start_element("track".into()).into(),
|
||||
XmlEvent::start_element("location".into()).into(),
|
||||
XmlEvent::characters(&self.url).into(),
|
||||
XmlEvent::end_element().into(),
|
||||
XmlEvent::start_element("title".into()).into(),
|
||||
XmlEvent::characters(&self.title).into(),
|
||||
XmlEvent::end_element().into(),
|
||||
XmlEvent::end_element().into()
|
||||
];
|
||||
for event in &events {
|
||||
w.write(event.into()).into()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn new(url: String, title: String) -> Track {
|
||||
Track {
|
||||
url: url,
|
||||
title: title,
|
||||
}
|
||||
}
|
||||
fn write_xml<W: Write>(self, w: &mut EventWriter<W>) -> XResult<()> {
|
||||
w.write(XmlEvent::start_element("track"))?;
|
||||
w.write(XmlEvent::start_element("location"))?;
|
||||
w.write(XmlEvent::characters(&self.url))?;
|
||||
w.write(XmlEvent::end_element())?;
|
||||
w.write(XmlEvent::start_element("title"))?;
|
||||
w.write(XmlEvent::characters(&self.title))?;
|
||||
w.write(XmlEvent::end_element())?;
|
||||
w.write(XmlEvent::end_element())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let file = File::open("VIDs").expect("Failed to open file!");
|
||||
let mut out = File::create("VIDs.xspf").unwrap();
|
||||
let mut writer = EmitterConfig::new().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");
|
||||
let mut writer = EmitterConfig::new()
|
||||
.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<()> {
|
||||
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(XmlEvent::start_element("trackList".into())).into()?;
|
||||
for track in tracks {
|
||||
track.write_xml(w)?;
|
||||
}
|
||||
w.write(XmlEvent::end_element().into()).into()?;
|
||||
w.write(XmlEvent::end_element().into()).into()?
|
||||
fn convert<I: Iterator<Item = Track>, W: Write>(tracks: I, w: &mut EventWriter<W>) -> XResult<()> {
|
||||
w.write(
|
||||
XmlEvent::start_element("playlist")
|
||||
.ns("", "http://xspf.org/ns/0/")
|
||||
.ns("vlc", "http://www.videolan.org/vlc/playlist/ns/0/"),
|
||||
)?;
|
||||
w.write(XmlEvent::start_element("trackList"))?;
|
||||
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> {
|
||||
let tracks = aria.scan(TrackBuilder::default(), |mut builder, line| {
|
||||
if !builder.url.is_some() {
|
||||
builder.url(line);
|
||||
} else {
|
||||
if line.starts_with("\t") {
|
||||
builder.title(line.chars().skip_while(|c| c != &'=').skip(1).collect::<String>());
|
||||
let track = Some(builder.build().unwrap());
|
||||
*builder = TrackBuilder::default();
|
||||
return Some(track);
|
||||
}
|
||||
}
|
||||
Some(None)
|
||||
}).filter_map(|track| track);
|
||||
Box::new(tracks)
|
||||
fn tracks<'a, I: Iterator<Item = String> + 'a>(aria: I) -> Box<Iterator<Item = Track> + 'a> {
|
||||
let tracks = aria
|
||||
.scan(TrackBuilder::default(), |builder, line| {
|
||||
if !builder.url.is_some() {
|
||||
builder.url(line);
|
||||
} else {
|
||||
if line.starts_with("\tout=") {
|
||||
builder.title(
|
||||
line.chars()
|
||||
.skip_while(|c| c != &'=')
|
||||
.skip(1)
|
||||
.collect::<String>(),
|
||||
);
|
||||
let track = Some(builder.build().unwrap());
|
||||
*builder = TrackBuilder::default();
|
||||
return Some(track);
|
||||
}
|
||||
}
|
||||
Some(None)
|
||||
})
|
||||
.filter_map(|track| track);
|
||||
Box::new(tracks)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user