From afb1d727009becdf845becd1f77f30d3d40898f6 Mon Sep 17 00:00:00 2001 From: shimunn <> Date: Sun, 14 Apr 2019 16:22:58 +0200 Subject: [PATCH 1/7] also convert to html --- Cargo.lock | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + rustfmt.toml | 1 + src/main.rs | 62 ++++++++++++-------- src/opts.rs | 18 ++++++ 5 files changed, 221 insertions(+), 23 deletions(-) create mode 100644 rustfmt.toml create mode 100644 src/opts.rs diff --git a/Cargo.lock b/Cargo.lock index a49fa81..ecba943 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,11 +1,51 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "aria2xspf" version = "0.1.0" dependencies = [ "derive_builder 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "atty" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clap" +version = "2.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "darling" version = "0.8.5" @@ -65,11 +105,24 @@ name = "fnv" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ident_case" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "0.4.27" @@ -86,6 +139,44 @@ dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "redox_syscall" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "structopt" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "structopt-derive" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.15.29" @@ -96,26 +187,97 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-segmentation" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "xml-rs" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum darling 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "52f20e669de9a5689aa54f3ca9ddc9e14ae5eef15028192bd2f7caf9376a0040" "checksum darling_core 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "672c68a636ed710f415c1fbaa48805db6c7400b8dc10f6b04e851ac1ea1b8c99" "checksum darling_macro 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e4115f0ff5e1a6092815889a480c4f1e4679991d7bfc99696b6f03980123c549" "checksum derive_builder 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a0ca533e6abb78f9108585535ce2ae0b14c8b4504e138a9a28eaf8ba2b270c1d" "checksum derive_builder_core 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb484fe06ba1dc5b82f88aff700191dfc127e02b06b35e302c169706168e2528" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" +"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3d0760c312538987d363c36c42339b55f5ee176ea8808bbe4543d484a291c8d1" +"checksum structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "528aeb7351d042e6ffbc2a6fb76a86f9b622fdf7c25932798e7a82cb03bc94c6" "checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" diff --git a/Cargo.toml b/Cargo.toml index 70efba1..6f37de1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2018" [dependencies] xml-rs = "0.8.0" derive_builder = "0.7.1" +structopt = "0.2.15" diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..7530651 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +max_width = 120 diff --git a/src/main.rs b/src/main.rs index a55277a..dc71cb0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,11 @@ #[macro_use] extern crate derive_builder; +#[macro_use] +extern crate structopt; +mod opts; + +use opts::*; use std::env; use std::fs::File; use std::io::{self, Write}; @@ -16,10 +21,7 @@ struct Track { impl Track { fn new(url: String, title: String) -> Track { - Track { - url: url, - title: title, - } + Track { url: url, title: title } } fn write_xml(self, w: &mut EventWriter) -> XResult<()> { w.write(XmlEvent::start_element("track"))?; @@ -31,15 +33,25 @@ impl Track { w.write(XmlEvent::end_element())?; w.write(XmlEvent::end_element()) } + + fn write_html(self, w: &mut EventWriter) -> XResult<()> { + w.write(XmlEvent::start_element("p"))?; + w.write(XmlEvent::characters(&self.title))?; + w.write(XmlEvent::end_element())?; + w.write(XmlEvent::start_element("video").attr("controls", ""))?; + w.write(XmlEvent::start_element("source").attr("src", &self.url))?; + 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); + let opts = Opts::from_args(); + let file = File::open(opts.input).expect("Failed to open file!"); + let mut out = File::create(opts.output).expect("Failed to open OUTPUT file!"); + let mut writer = EmitterConfig::new().perform_indent(true).create_writer(&mut out); convert( + opts.html, tracks( BufReader::new(file) .lines() @@ -50,15 +62,24 @@ fn main() { .expect("Failed to parse"); } -fn convert, W: Write>(tracks: I, w: &mut EventWriter) -> 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"))?; +fn convert, W: Write>(html: bool, tracks: I, w: &mut EventWriter) -> XResult<()> { + if html { + w.write(XmlEvent::start_element("html"))?; + w.write(XmlEvent::start_element("body"))?; + } else { + 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)?; + if html { + track.write_html(w)?; + } else { + track.write_xml(w)?; + } } w.write(XmlEvent::end_element())?; w.write(XmlEvent::end_element()) @@ -71,12 +92,7 @@ fn tracks<'a, I: Iterator + 'a>(aria: I) -> Box Date: Sun, 14 Apr 2019 18:52:51 +0200 Subject: [PATCH 2/7] disable preload --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index dc71cb0..6fec91f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,7 +38,7 @@ impl Track { w.write(XmlEvent::start_element("p"))?; w.write(XmlEvent::characters(&self.title))?; w.write(XmlEvent::end_element())?; - w.write(XmlEvent::start_element("video").attr("controls", ""))?; + w.write(XmlEvent::start_element("video").attr("controls", "controls").attr("preload", "none"))?; w.write(XmlEvent::start_element("source").attr("src", &self.url))?; w.write(XmlEvent::end_element())?; w.write(XmlEvent::end_element()) From 2a253fcea1633881de22779e814d2a94d82d7443 Mon Sep 17 00:00:00 2001 From: Shimun Date: Thu, 18 Apr 2019 20:41:12 +0200 Subject: [PATCH 3/7] added config option to include resources into generated html --- Cargo.lock | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 5 ++ src/conf.rs | 10 +++ src/main.rs | 57 ++++++++++++- 4 files changed, 312 insertions(+), 2 deletions(-) create mode 100644 src/conf.rs diff --git a/Cargo.lock b/Cargo.lock index ecba943..9553e66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,15 +8,37 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "argon2rs" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "aria2xspf" version = "0.1.0" dependencies = [ "derive_builder 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arrayvec" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "atty" version = "0.2.11" @@ -27,11 +49,57 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "autocfg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "backtrace" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bitflags" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "clap" version = "2.33.0" @@ -46,6 +114,19 @@ dependencies = [ "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "darling" version = "0.8.5" @@ -100,11 +181,46 @@ dependencies = [ "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fnv" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "heck" version = "0.3.1" @@ -118,11 +234,21 @@ name = "ident_case" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lazy_static" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "libc" version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "nodrop" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "0.4.27" @@ -139,6 +265,40 @@ dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.54" @@ -152,6 +312,42 @@ dependencies = [ "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "redox_users" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_derive" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "strsim" version = "0.8.0" @@ -187,6 +383,17 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "synstructure" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termion" version = "1.5.1" @@ -205,6 +412,14 @@ dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "toml" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicode-segmentation" version = "1.2.1" @@ -251,28 +466,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" +"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" +"checksum backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f106c02a3604afcdc0df5d36cc47b44b55917dbaf3d808f71c163a0ddba64637" +"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +"checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83" +"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum darling 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "52f20e669de9a5689aa54f3ca9ddc9e14ae5eef15028192bd2f7caf9376a0040" "checksum darling_core 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "672c68a636ed710f415c1fbaa48805db6c7400b8dc10f6b04e851ac1ea1b8c99" "checksum darling_macro 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e4115f0ff5e1a6092815889a480c4f1e4679991d7bfc99696b6f03980123c549" "checksum derive_builder 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a0ca533e6abb78f9108585535ce2ae0b14c8b4504e138a9a28eaf8ba2b270c1d" "checksum derive_builder_core 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb484fe06ba1dc5b82f88aff700191dfc127e02b06b35e302c169706168e2528" +"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" +"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa" +"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828" +"checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288" +"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" +"checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4" +"checksum serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "58fc82bec244f168b23d1963b45c8bf5726e9a15a9d146a067f9081aeed2de79" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3d0760c312538987d363c36c42339b55f5ee176ea8808bbe4543d484a291c8d1" "checksum structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "528aeb7351d042e6ffbc2a6fb76a86f9b622fdf7c25932798e7a82cb03bc94c6" "checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2" +"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87c5890a989fa47ecdc7bcb4c63a77a82c18f306714104b1decfd722db17b39e" "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" diff --git a/Cargo.toml b/Cargo.toml index 6f37de1..bc02ac0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,8 @@ edition = "2018" xml-rs = "0.8.0" derive_builder = "0.7.1" structopt = "0.2.15" +toml = "0.5.0" +serde_derive = "1.0.90" +dirs = "1.0.5" +serde = "1.0.90" +lazy_static = "1.3.0" diff --git a/src/conf.rs b/src/conf.rs new file mode 100644 index 0000000..0260920 --- /dev/null +++ b/src/conf.rs @@ -0,0 +1,10 @@ +#[derive(Deserialize, Default)] +pub struct Config { + pub include: Includes, +} + +#[derive(Deserialize, Default)] +pub struct Includes { + pub js: Vec, + pub css: Vec, +} diff --git a/src/main.rs b/src/main.rs index 6fec91f..344845c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,15 +2,22 @@ extern crate derive_builder; #[macro_use] extern crate structopt; +#[macro_use] +extern crate serde_derive; +#[macro_use] +extern crate lazy_static; +mod conf; mod opts; +use conf::*; use opts::*; use std::env; use std::fs::File; -use std::io::{self, Write}; +use std::io::{self, Read, Write}; use std::io::{BufRead, BufReader}; +use dirs; use xml::writer::{EmitterConfig, EventWriter, Result as XResult, XmlEvent}; #[derive(Builder, Debug)] @@ -38,13 +45,41 @@ impl Track { w.write(XmlEvent::start_element("p"))?; w.write(XmlEvent::characters(&self.title))?; w.write(XmlEvent::end_element())?; - w.write(XmlEvent::start_element("video").attr("controls", "controls").attr("preload", "none"))?; + w.write( + XmlEvent::start_element("video") + .attr("controls", "controls") + .attr("preload", "none"), + )?; w.write(XmlEvent::start_element("source").attr("src", &self.url))?; w.write(XmlEvent::end_element())?; w.write(XmlEvent::end_element()) } } +lazy_static! { + static ref CONFIG: Config = config().unwrap_or(Config::default()); +} + +fn config() -> Option { + match dirs::config_dir() { + None => { + eprintln!("Couldn't locate configuration directory, proceeding with default config"); + None + } + Some(dir) => { + let mut file_path = dir; + file_path.push("aria2xspf.toml"); + if !file_path.exists() { + return None; + } + let mut file = File::open(file_path).expect("Failed to load config file"); + let mut contents = String::new(); + file.read_to_string(&mut contents).expect("Failed to decode config"); + Some(toml::from_str(&contents).expect("Failed to parse config")) + } + } +} + fn main() { let opts = Opts::from_args(); let file = File::open(opts.input).expect("Failed to open file!"); @@ -65,6 +100,24 @@ fn main() { fn convert, W: Write>(html: bool, tracks: I, w: &mut EventWriter) -> XResult<()> { if html { w.write(XmlEvent::start_element("html"))?; + { + w.write(XmlEvent::start_element("head"))?; + for url in CONFIG.include.js.iter() { + w.write( + XmlEvent::start_element("script") + .attr("type", "text/javascript") + .attr("src", url), + )?; + } + for url in CONFIG.include.css.iter() { + w.write( + XmlEvent::start_element("link") + .attr("rel", "stylesheet") + .attr("href", url), + )?; + } + w.write(XmlEvent::end_element())?; + } w.write(XmlEvent::start_element("body"))?; } else { w.write( From 824dedae00b774131629f63c6e3b5010907bd45c Mon Sep 17 00:00:00 2001 From: shimunn <> Date: Fri, 26 Apr 2019 15:27:54 +0200 Subject: [PATCH 4/7] script to persist playback position --- aria2xspf.toml | 3 +++ js/resume.js | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 aria2xspf.toml create mode 100644 js/resume.js diff --git a/aria2xspf.toml b/aria2xspf.toml new file mode 100644 index 0000000..663dab7 --- /dev/null +++ b/aria2xspf.toml @@ -0,0 +1,3 @@ +[include] +js = ["https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js", "https://raw.githubusercontent.com/shimunn/aria2xspf/include/js/resume.js"] +css = [] diff --git a/js/resume.js b/js/resume.js new file mode 100644 index 0000000..e998151 --- /dev/null +++ b/js/resume.js @@ -0,0 +1,22 @@ +(function($, window) { + $(window).on('load', function() { + $("video").each(function(e) { + var src = this.currentSrc; + console.log(src); + var start = window.localStorage[btoa(src)]; + if (start) { + this.currentTime = parseFloat(start); + } + }); + }); + setInterval(function() { + $("video").each(function(e) { + var src = this.currentSrc; + var time = this.currentTime; + if (time) { + window.localStorage[btoa(src)] = time; + console.log("Persisted video progress at: " + time); + } + }); + }, 5000); +}($, window)); From 312ce4a80ba1db10c776fe058d92533c0435bb92 Mon Sep 17 00:00:00 2001 From: shimunn <> Date: Fri, 26 Apr 2019 15:37:11 +0200 Subject: [PATCH 5/7] html style closing tag --- src/main.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.rs b/src/main.rs index 344845c..774aeff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -108,6 +108,8 @@ fn convert, W: Write>(html: bool, tracks: I, w: &mut E .attr("type", "text/javascript") .attr("src", url), )?; + w.write(XmlEvent::characters(""))?; + w.write(XmlEvent::end_element())?; } for url in CONFIG.include.css.iter() { w.write( @@ -115,6 +117,8 @@ fn convert, W: Write>(html: bool, tracks: I, w: &mut E .attr("rel", "stylesheet") .attr("href", url), )?; + w.write(XmlEvent::characters(""))?; + w.write(XmlEvent::end_element())?; } w.write(XmlEvent::end_element())?; } From 61dc6b7d8e1c180cee1ded8c920c216ffc7c7f3a Mon Sep 17 00:00:00 2001 From: shimunn <> Date: Fri, 26 Apr 2019 16:26:46 +0200 Subject: [PATCH 6/7] indicate last position --- js/resume.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/js/resume.js b/js/resume.js index e998151..2b981c3 100644 --- a/js/resume.js +++ b/js/resume.js @@ -1,10 +1,23 @@ (function($, window) { + window.jumpVid = function (id, time) { + $("video").each(function(e) { + if(btoa(this.currentSrc) == id) { + this.currentTime = time; + this.play(); + } + }); + }; $(window).on('load', function() { $("video").each(function(e) { var src = this.currentSrc; + var id = btoa(src); console.log(src); - var start = window.localStorage[btoa(src)]; + var start = window.localStorage[id]; if (start) { + if(!$(this).prev().find(".resume").length){ + $(this).prev().append('
'); + } + $(this).prev().find(".resume").html('Resume @'+Math.round(start / 60) +'min'); this.currentTime = parseFloat(start); } }); From 8a1b718709c0800a7b1eb5747a6a1767d026605e Mon Sep 17 00:00:00 2001 From: Shimun Date: Sat, 8 Jun 2019 20:04:24 +0200 Subject: [PATCH 7/7] prevent user from overrriding source file --- src/main.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 774aeff..fb5e640 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,13 +11,13 @@ mod conf; mod opts; use conf::*; +use dirs; use opts::*; use std::env; use std::fs::File; -use std::io::{self, Read, Write}; +use std::io::{self, Read, Stdin, Write}; use std::io::{BufRead, BufReader}; - -use dirs; +use std::process::exit; use xml::writer::{EmitterConfig, EventWriter, Result as XResult, XmlEvent}; #[derive(Builder, Debug)] @@ -82,6 +82,14 @@ fn config() -> Option { fn main() { let opts = Opts::from_args(); + if opts.input == opts.output { + eprintln!("Input and output are the same file! {:?}\nContinue(y/n): ", opts.input); + match io::stdin().bytes().next() { + Some(Ok(r)) if r as char == 'y' => (), + Some(Ok(_)) => exit(1), + _ => (), //Stdin closed, assume in == out is intentional + } + } let file = File::open(opts.input).expect("Failed to open file!"); let mut out = File::create(opts.output).expect("Failed to open OUTPUT file!"); let mut writer = EmitterConfig::new().perform_indent(true).create_writer(&mut out); @@ -108,8 +116,8 @@ fn convert, W: Write>(html: bool, tracks: I, w: &mut E .attr("type", "text/javascript") .attr("src", url), )?; - w.write(XmlEvent::characters(""))?; - w.write(XmlEvent::end_element())?; + w.write(XmlEvent::characters(""))?; + w.write(XmlEvent::end_element())?; } for url in CONFIG.include.css.iter() { w.write( @@ -118,7 +126,7 @@ fn convert, W: Write>(html: bool, tracks: I, w: &mut E .attr("href", url), )?; w.write(XmlEvent::characters(""))?; - w.write(XmlEvent::end_element())?; + w.write(XmlEvent::end_element())?; } w.write(XmlEvent::end_element())?; }