Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/add full date capabilities #34

Merged
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
8 changes: 8 additions & 0 deletions src/anytag.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::*;
use id3::Timestamp;

#[derive(Default)]
pub struct AnyTag<'a> {
pub config: Config,
pub title: Option<&'a str>,
pub artists: Option<Vec<&'a str>>,
pub date: Option<Timestamp>,
pub year: Option<i32>,
pub duration: Option<f64>,
pub album_title: Option<&'a str>,
Expand Down Expand Up @@ -39,6 +41,12 @@ impl<'a> AnyTag<'a> {
self.artists.as_deref()
}
// set_artists; add_artist
pub fn date(&self) -> Option<Timestamp> {
self.date
}
pub fn set_date(&mut self, date: Timestamp) {
self.date = Some(date);
}
pub fn year(&self) -> Option<i32> {
self.year
}
Expand Down
27 changes: 23 additions & 4 deletions src/components/flac_tag.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::*;
use id3::Timestamp;
use metaflac;
use std::str::FromStr;

pub use metaflac::Tag as FlacInnerTag;

Expand All @@ -14,6 +16,9 @@ impl<'a> From<AnyTag<'a>> for FlacTag {
if let Some(v) = inp.artists_as_string() {
t.set_artist(&v)
}
if let Some(v) = inp.date {
t.set_date(v)
}
if let Some(v) = inp.year {
t.set_year(v)
}
Expand Down Expand Up @@ -44,6 +49,7 @@ impl<'a> From<&'a FlacTag> for AnyTag<'a> {
let tag = Self {
title: inp.title(),
artists: inp.artists(),
date: inp.date(),
year: inp.year(),
duration: inp.duration(),
album_title: inp.album_title(),
Expand Down Expand Up @@ -104,20 +110,33 @@ impl AudioTagEdit for FlacTag {
self.remove("ARTIST");
}

fn date(&self) -> Option<Timestamp> {
if let Some(Ok(timestamp)) = self.get_first("DATE").map(Timestamp::from_str) {
Some(timestamp)
} else {
None
}
}
fn set_date(&mut self, date: Timestamp) {
self.set_first("DATE", &date.to_string());
}
fn remove_date(&mut self) {
self.remove("DATE");
}

fn year(&self) -> Option<i32> {
if let Some(Ok(y)) = self
if let Some(Ok(y)) = self.get_first("YEAR").map(|s| s.parse::<i32>()) {
Some(y)
} else if let Some(Ok(y)) = self
.get_first("DATE")
.map(|s| s.chars().take(4).collect::<String>().parse::<i32>())
{
Some(y)
} else if let Some(Ok(y)) = self.get_first("YEAR").map(|s| s.parse::<i32>()) {
Some(y)
} else {
None
}
}
fn set_year(&mut self, year: i32) {
self.set_first("DATE", &year.to_string());
self.set_first("YEAR", &year.to_string());
}
fn remove_year(&mut self) {
Expand Down
44 changes: 17 additions & 27 deletions src/components/id3_tag.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::*;
use id3::{self, Content, Frame, TagLike, Timestamp, Version};
use id3::{self, Content, Frame, TagLike, Timestamp};

pub use id3::Tag as Id3v2InnerTag;

Expand All @@ -12,6 +12,7 @@ impl<'a> From<&'a Id3v2Tag> for AnyTag<'a> {

title: inp.title(),
artists: inp.artists(),
date: inp.date(),
year: inp.year(),
duration: Some(inp.inner.duration().unwrap() as f64),
album_title: inp.album_title(),
Expand Down Expand Up @@ -40,6 +41,9 @@ impl<'a> From<AnyTag<'a>> for Id3v2Tag {
if let Some(v) = inp.artists_as_string() {
t.set_artist(&v)
}
if let Some(v) = inp.date() {
t.set_date_recorded(v)
}
if let Some(v) = inp.year {
t.set_year(v)
}
Expand Down Expand Up @@ -102,35 +106,21 @@ impl AudioTagEdit for Id3v2Tag {
self.inner.remove_artist();
}

fn year(&self) -> Option<i32> {
if self.inner.version() == Version::Id3v23 {
if let ret @ Some(_) = self.inner.year() {
return ret;
}
}
fn date(&self) -> Option<Timestamp> {
self.inner.date_recorded()
}
fn set_date(&mut self, timestamp: Timestamp) {
self.inner.set_date_recorded(timestamp)
}
fn remove_date(&mut self) {
self.inner.remove_date_recorded()
}

self.inner.date_recorded().map(|timestamp| timestamp.year)
fn year(&self) -> Option<i32> {
self.inner.year()
}
fn set_year(&mut self, year: i32) {
if self.inner.version() == Version::Id3v23 {
self.inner.set_year(year);
return;
}

if let Some(mut timestamp) = self.inner.date_recorded() {
timestamp.year = year;
self.inner.set_date_recorded(timestamp);
return;
}

self.inner.set_date_recorded(Timestamp {
year,
month: None,
day: None,
hour: None,
minute: None,
second: None,
});
self.inner.set_year(year);
}
fn remove_year(&mut self) {
self.inner.remove_date_recorded();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be good once this is added back. I missed this in the review. :)

Copy link
Contributor Author

@BSteffaniak BSteffaniak Sep 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added back

Expand Down
18 changes: 18 additions & 0 deletions src/components/mp4_tag.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::*;
use id3::Timestamp;
use mp4ameta::{self, ImgFmt};
use std::str::FromStr;

pub use mp4ameta::Tag as Mp4InnerTag;

Expand All @@ -9,6 +11,7 @@ impl<'a> From<&'a Mp4Tag> for AnyTag<'a> {
fn from(inp: &'a Mp4Tag) -> Self {
let title = inp.title();
let artists = inp.artists().map(|i| i.into_iter().collect::<Vec<_>>());
let date = inp.date();
let year = inp.year();
let duration = inp.duration();
let album_title = inp.album_title();
Expand All @@ -29,6 +32,7 @@ impl<'a> From<&'a Mp4Tag> for AnyTag<'a> {
config: inp.config,
title,
artists,
date,
year,
duration,
album_title,
Expand Down Expand Up @@ -137,6 +141,20 @@ impl AudioTagEdit for Mp4Tag {
self.inner.add_artist(v);
}

fn date(&self) -> Option<Timestamp> {
if let Some(Ok(date)) = self.inner.year().map(Timestamp::from_str) {
Some(date)
} else {
None
}
}
fn set_date(&mut self, date: Timestamp) {
self.inner.set_year(date.to_string())
}
fn remove_date(&mut self) {
self.inner.remove_year()
}

fn year(&self) -> Option<i32> {
self.inner.year().and_then(|x| str::parse(x).ok())
}
Expand Down
5 changes: 5 additions & 0 deletions src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::*;
use id3::Timestamp;

pub trait AudioTag: AudioTagEdit + AudioTagWrite + ToAnyTag {}

Expand Down Expand Up @@ -31,6 +32,10 @@ pub trait AudioTagEdit: AudioTagConfig {
self.set_artist(artist);
}

fn date(&self) -> Option<Timestamp>;
fn set_date(&mut self, date: Timestamp);
fn remove_date(&mut self);

fn year(&self) -> Option<i32>;
fn set_year(&mut self, year: i32);
fn remove_year(&mut self);
Expand Down
11 changes: 11 additions & 0 deletions tests/io.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use audiotags::{MimeType, Picture, Tag};
use id3::Timestamp;
use std::ffi::OsString;
use std::fs;
use std::path::Path;
use std::str::FromStr;
use tempfile::Builder;

macro_rules! test_file {
Expand All @@ -28,6 +30,15 @@ macro_rules! test_file {
assert!(tags.artist().is_none());
tags.remove_artist();

tags.set_date(Timestamp::from_str("2020-05-22").unwrap());
assert_eq!(
tags.date(),
Some(Timestamp::from_str("2020-05-22").unwrap())
);
tags.remove_date();
assert!(tags.date().is_none());
tags.remove_date();

tags.set_year(2020);
assert_eq!(tags.year(), Some(2020));
tags.remove_year();
Expand Down