Skip to content

Commit

Permalink
add support for <podcast:valueTimeSplit>
Browse files Browse the repository at this point in the history
  • Loading branch information
joksas committed Feb 9, 2024
1 parent d187671 commit d112ae0
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 1 deletion.
19 changes: 19 additions & 0 deletions src/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,22 @@ impl std::fmt::Display for Number {
}
}
}

/// Duration.
#[derive(Debug, PartialEq, Eq)]
pub enum Duration {
Duration(chrono::Duration),
Other(Other),
}

impl Duration {
pub fn parse_from_int_string(s: &str) -> Self {
match s.parse::<u64>() {
Ok(x) => Self::Duration(chrono::Duration::seconds(x as i64)),
Err(_) => Self::Other((
s.to_string(),
"should be a non-negative integer".to_string(),
)),
}
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub mod itunes;
/// Implementation details adapted from <https://podcastindex.org/namespace/1.0>.
pub mod podcast;

pub use crate::basic::{Bool, Float, Integer, Number};
pub use crate::basic::{Bool, Duration, Float, Integer, Number};
pub use crate::language::{
Language, LanguageChinese, LanguageDutch, LanguageEnglish, LanguageFrench, LanguageGerman,
LanguageItalian, LanguagePortugese, LanguageRomanian, LanguageRussian, LanguageSpanish,
Expand Down
53 changes: 53 additions & 0 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,12 @@ fn parse_podcast_value(value: roxmltree::Node) -> podcast::Value {
.value_recipient
.push(parse_podcast_value_recipient(child));
}

if let (Some(NS_PODCAST_1 | NS_PODCAST_2), "valueTimeSplit") = (namespace, tag_name) {
new_value
.value_time_split
.push(parse_podcast_value_time_split(child));
}
}

new_value
Expand Down Expand Up @@ -781,6 +787,53 @@ fn parse_podcast_value_recipient(value_recipient: roxmltree::Node) -> podcast::V
new_value_recipient
}

fn parse_podcast_value_time_split(value_time_split: roxmltree::Node) -> podcast::ValueTimeSplit {
let mut new_value_time_split = podcast::ValueTimeSplit {
..Default::default()
};

for attribute in value_time_split.attributes() {
match attribute.name() {
"startTime" => {
new_value_time_split.start_time =
Some(basic::Duration::parse_from_int_string(attribute.value()))
}
"duration" => {
new_value_time_split.duration =
Some(basic::Duration::parse_from_int_string(attribute.value()))
}
"remoteStartTime" => {
new_value_time_split.remote_start_time =
Some(basic::Duration::parse_from_int_string(attribute.value()))
}
"remotePercentage" => {
new_value_time_split.remote_percentage =
Some(Integer::parse(attribute.value(), NumberConstraint::None))
}
_ => {}
}
}

for child in value_time_split.children() {
let namespace = child.tag_name().namespace();
let tag_name = child.tag_name().name();

if let (Some(NS_PODCAST_1 | NS_PODCAST_2), "valueRecipient") = (namespace, tag_name) {
new_value_time_split
.value_recipient
.push(parse_podcast_value_recipient(child));
}

if let (Some(NS_PODCAST_1 | NS_PODCAST_2), "remoteItem") = (namespace, tag_name) {
new_value_time_split
.remote_item
.push(parse_podcast_remote_item(child));
}
}

new_value_time_split
}

pub fn parse_podcast_images(images: roxmltree::Node) -> podcast::Images {
let mut new_images = podcast::Images {
..Default::default()
Expand Down
12 changes: 12 additions & 0 deletions src/podcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ pub struct Value {
pub method: Option<ValueMethod>,
pub suggested: Option<basic::Float>,
pub value_recipient: Vec<ValueRecipient>,
pub value_time_split: Vec<ValueTimeSplit>,
}

/// Destination for payments to be sent to during consumption of enclosed media.
Expand Down Expand Up @@ -269,3 +270,14 @@ pub struct RemoteItem {
pub item_guid: Option<GuidValue>,
pub medium: Option<Medium>,
}

/// This element allows different value splits for a certain period of time.
#[derive(Debug, PartialEq, Eq, Default)]
pub struct ValueTimeSplit {
pub start_time: Option<crate::Duration>,
pub duration: Option<crate::Duration>,
pub remote_start_time: Option<crate::Duration>,
pub remote_percentage: Option<basic::Integer>,
pub remote_item: Vec<RemoteItem>,
pub value_recipient: Vec<ValueRecipient>,
}
4 changes: 4 additions & 0 deletions tests/data/podcast_namespace_example.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
<podcast:value type="lightning" method="keysend" suggested="0.00000005000">
<podcast:valueRecipient name="podcaster" type="node" address="036557ea56b3b86f08be31bcd2557cae8021b0e3a9413f0c0e52625c6696972e57" split="99" />
<podcast:valueRecipient name="hosting company" type="node" address="036557ea56b3b86f08be31bcd2557cae8021b0e3a9413f0c0e52625c6696972e57" split="1" />

<podcast:valueTimeSplit startTime="60" duration="237" remotePercentage="95">
<podcast:remoteItem itemGuid="https://podcastindex.org/podcast/4148683#1" feedGuid="a94f5cc9-8c58-55fc-91fe-a324087a655b" medium="music" />
</podcast:valueTimeSplit>
</podcast:value>

<podcast:trailer pubdate="Thu, 01 Apr 2021 08:00:00 EST" url="https://example.org/trailers/teaser" length="12345678" type="audio/mp3">Coming April 1st, 2021</podcast:trailer>
Expand Down
19 changes: 19 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ fn deserialize() {
..Default::default()
},
},
value_time_split: vec![],
}],
podcast_medium: vec![podcast::Medium::Music],
podcast_images: vec![podcast::Images {
Expand Down Expand Up @@ -312,6 +313,7 @@ fn deserialize() {
method: Some(podcast::ValueMethod::Keysend),
suggested: Some(Float::Ok(0.00000015)),
value_recipient: vec!{},
value_time_split: vec![],
}],
podcast_social_interact: vec! {
podcast::SocialInteract{
Expand Down Expand Up @@ -462,6 +464,21 @@ fn deserialize() {
..Default::default()
},
},
value_time_split: vec![
podcast::ValueTimeSplit{
start_time: Some(badpod::Duration::Duration(chrono::Duration::minutes(1))),
duration: Some(badpod::Duration::Duration(chrono::Duration::minutes(3) + chrono::Duration::seconds(57))),
remote_start_time: None,
remote_percentage: Some(Integer::Ok(95)),
value_recipient: vec![],
remote_item: vec![podcast::RemoteItem{
feed_guid: Some(podcast::Guid::Ok("a94f5cc9-8c58-55fc-91fe-a324087a655b".into())),
feed_url: None,
item_guid: Some(GuidValue::Url(url::Url::parse("https://podcastindex.org/podcast/4148683#1").unwrap())),
medium: Some(podcast::Medium::Music),
}],
}
],
}],
podcast_trailer: vec!{
podcast::Trailer{
Expand Down Expand Up @@ -736,6 +753,7 @@ fn deserialize() {
..Default::default()
},
},
value_time_split: vec![],
}],
podcast_social_interact: vec!{
podcast::SocialInteract{
Expand Down Expand Up @@ -930,6 +948,7 @@ fn deserialize() {
..Default::default()
},
},
value_time_split: vec![],
}],
..Default::default()
},
Expand Down

0 comments on commit d112ae0

Please sign in to comment.