Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/display_duration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use super::*;

pub(crate) struct DisplayDuration(pub(crate) Duration);

impl Display for DisplayDuration {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let seconds = self.0.as_secs();

let hours = seconds / 3600;
let minutes = seconds / 60 % 60;
let seconds = seconds % 60;

if hours > 0 {
write!(f, "{hours}:{minutes:02}:{seconds:02}")
} else {
write!(f, "{minutes}:{seconds:02}")
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn display() {
#[track_caller]
fn case(duration: Duration, expected: &str) {
assert_eq!(DisplayDuration(duration).to_string(), expected);
}

case(Duration::ZERO, "0:00");
case(Duration::from_millis(59999), "0:59");
case(Duration::from_mins(1), "1:00");
case(Duration::from_secs(225), "3:45");
case(Duration::from_secs(3599), "59:59");
case(Duration::from_hours(1), "1:00:00");
case(Duration::from_secs(3723), "1:02:03");
}
}
31 changes: 26 additions & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,32 +462,53 @@ pub enum Error {
},
#[snafu(display("authentication tokens may only be used over HTTPS or loopback"))]
TokenOverHttp { backtrace: Option<Backtrace> },
#[snafu(display("failed to decode FLAC track `{path}`"))]
#[snafu(display("failed to decode track `{path}`"))]
TrackDecode {
backtrace: Option<Backtrace>,
path: DisplayPath,
source: claxon::Error,
},
#[snafu(display("FLAC track `{path}` has empty `{tag}` tag"))]
#[snafu(display("track `{path}` has {actual} samples but metadata sample count is {expected}"))]
TrackSampleCountMismatch {
actual: u64,
backtrace: Option<Backtrace>,
expected: u64,
path: DisplayPath,
},
#[snafu(display("track `{path}` has unknown sample count"))]
TrackSampleCountUnknown {
backtrace: Option<Backtrace>,
path: DisplayPath,
},
#[snafu(display(
"track `{path}` has sample rate {actual} but metadata sample rate is {expected}"
))]
TrackSampleRateMismatch {
actual: u64,
backtrace: Option<Backtrace>,
expected: u64,
path: DisplayPath,
},
#[snafu(display("track `{path}` has empty `{tag}` tag"))]
TrackTagEmpty {
backtrace: Option<Backtrace>,
path: DisplayPath,
tag: &'static str,
},
#[snafu(display("FLAC track `{path}` has invalid `{tag}` tag"))]
#[snafu(display("track `{path}` has invalid `{tag}` tag"))]
TrackTagInvalid {
backtrace: Option<Backtrace>,
path: DisplayPath,
source: TextError,
tag: &'static str,
},
#[snafu(display("FLAC track `{path}` is missing `{tag}` tag"))]
#[snafu(display("track `{path}` is missing `{tag}` tag"))]
TrackTagMissing {
backtrace: Option<Backtrace>,
path: DisplayPath,
tag: &'static str,
},
#[snafu(display("FLAC track `{path}` has multiple `{tag}` tags"))]
#[snafu(display("track `{path}` has multiple `{tag}` tags"))]
TrackTagMultiple {
backtrace: Option<Backtrace>,
path: DisplayPath,
Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use {
decode_error::DecodeError,
dimensions::Dimensions,
directory_tree_entry::DirectoryTreeEntry,
display_duration::DisplayDuration,
display_path::DisplayPath,
display_secret::DisplaySecret,
entries::Entries,
Expand Down Expand Up @@ -87,6 +88,7 @@ use {
sign_options::SignOptions,
signature_error::SignatureError,
static_asset::StaticAsset,
streaminfo::Streaminfo,
style::Style,
subcommand::Subcommand,
templates::PageHtml,
Expand Down Expand Up @@ -229,6 +231,7 @@ mod dimensions;
mod directory;
mod directory_tree;
mod directory_tree_entry;
mod display_duration;
mod display_path;
mod display_secret;
mod encode;
Expand Down Expand Up @@ -291,6 +294,7 @@ mod signature_error;
mod sorted_set;
mod statement;
mod static_asset;
mod streaminfo;
mod style;
mod subcommand;
pub mod templates;
Expand Down
2 changes: 1 addition & 1 deletion src/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ mod tests {
Media::Audio {
tracks: vec!["foo.flac".parse().unwrap(), "bar.flac".parse().unwrap()],
},
"8200a10082a5006001600268666f6f2e666c616303600400a50060016002686261722e666c616303600400",
"8200a10082a7006001600268666f6f2e666c61630300040005600600a70060016002686261722e666c61630300040005600600",
);
}

Expand Down
16 changes: 13 additions & 3 deletions src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,18 @@ impl Metadata {
}
}

if let Some(Media::Image { images }) = &self.media {
for image in images {
image.check_content(root)?;
match &self.media {
Some(Media::Audio { tracks }) => {
for track in tracks {
track.check_content(root)?;
}
}
Some(Media::Image { images }) => {
for image in images {
image.check_content(root)?;
}
}
None => {}
}

Ok(())
Expand Down Expand Up @@ -362,6 +370,8 @@ mod tests {
album: "bar".parse().unwrap(),
artist: "baz".parse().unwrap(),
filename: "track.flac".parse().unwrap(),
sample_count: 2,
sample_rate: 1,
title: "foo".parse().unwrap(),
ty: AudioType::Flac,
}],
Expand Down
4 changes: 4 additions & 0 deletions src/streaminfo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub(crate) struct Streaminfo {
pub(crate) sample_count: u64,
pub(crate) sample_rate: u64,
}
2 changes: 2 additions & 0 deletions src/subcommand/serve/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,8 @@ fn package_page_renders_audio_media() {
album: "qux".parse().unwrap(),
artist: "baz".parse().unwrap(),
filename: "foo.flac".parse().unwrap(),
sample_count: 9_922_500,
sample_rate: 44100,
title: "foo".parse().unwrap(),
ty: AudioType::Flac,
},
Expand Down
70 changes: 70 additions & 0 deletions src/templates/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,73 @@ impl Page for PackageHtml {
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn audio() {
let metadata = Metadata {
media: Some(Media::Audio {
tracks: vec![
Track {
album: "qux".parse().unwrap(),
artist: "baz".parse().unwrap(),
filename: "foo.flac".parse().unwrap(),
sample_count: 9_922_500,
sample_rate: 44100,
title: "foo".parse().unwrap(),
ty: AudioType::Flac,
},
Track {
album: "qux".parse().unwrap(),
artist: "baz".parse().unwrap(),
filename: "bar.flac".parse().unwrap(),
sample_count: 44100,
sample_rate: 44100,
title: "bar".parse().unwrap(),
ty: AudioType::Flac,
},
],
}),
..default()
};

assert_eq!(
PackageHtml {
fingerprint: test::FINGERPRINT.parse().unwrap(),
metadata: Some(metadata),
}
.to_string(),
unindent(&format!(
"
<h1>{fingerprint}</h1>
<a href=/directory/{hash}>files</a>
<dl>
<dt>fingerprint</dt>
<dd>{fingerprint}</dd>
<dt>media</dt>
<dd>audio</dd>
<dt>tracks</dt>
<dd>2</dd>
<dt>duration</dt>
<dd>3:46</dd>
</dl>
<ul>
<li>
<a href=/package/{fingerprint}/1>foo</a>
3:45
</li>
<li>
<a href=/package/{fingerprint}/2>bar</a>
0:01
</li>
</ul>
",
fingerprint = test::FINGERPRINT,
hash = test::HASH,
)),
);
}
}
44 changes: 44 additions & 0 deletions src/templates/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,47 @@ impl Page for TrackHtml {
format!("{} · filepack", self.track().title)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn track() {
let metadata = Metadata {
media: Some(Media::Audio {
tracks: vec![Track {
album: "qux".parse().unwrap(),
artist: "baz".parse().unwrap(),
filename: "foo.flac".parse().unwrap(),
sample_count: 9_922_500,
sample_rate: 44100,
title: "foo".parse().unwrap(),
ty: AudioType::Flac,
}],
}),
..default()
};

assert_eq!(
TrackHtml {
fingerprint: test::FINGERPRINT.parse().unwrap(),
metadata,
track: 0,
}
.to_string(),
unindent(&format!(
"
<img src=/artwork/{fingerprint}>
<div class=info>
<div class=title>foo</div>
<div class=artist>baz</div>
<div class=album>qux</div>
</div>
<audio controls src=/media/audio/{fingerprint}/track/1></audio>
",
fingerprint = test::FINGERPRINT,
)),
);
}
}
5 changes: 3 additions & 2 deletions src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub(crate) fn checksum(s: &str) -> String {
.collect()
}

pub(crate) fn flac(comments: &[&str]) -> Vec<u8> {
pub(crate) fn flac(comments: &[&str], sample_count: u32) -> Vec<u8> {
let mut bytes = b"fLaC".to_vec();

bytes.push(if comments.is_empty() { 0x80 } else { 0x00 });
Expand All @@ -67,7 +67,8 @@ pub(crate) fn flac(comments: &[&str]) -> Vec<u8> {
bytes.extend_from_slice(&4096u16.to_be_bytes());
bytes.extend_from_slice(&[0; 6]);
bytes.extend_from_slice(&[0x0a, 0xc4, 0x42, 0xf0]);
bytes.extend_from_slice(&[0; 20]);
bytes.extend_from_slice(&sample_count.to_be_bytes());
bytes.extend_from_slice(&[0; 16]);

if !comments.is_empty() {
let mut body = Vec::new();
Expand Down
Loading
Loading