Switch from chrono to time

This commit is contained in:
Roderick van Domburg 2022-01-14 23:28:09 +01:00
parent 7fe13be564
commit dbeeb0f991
No known key found for this signature in database
GPG key ID: A9EF5222A26F0451
12 changed files with 78 additions and 75 deletions

14
Cargo.lock generated
View file

@ -237,7 +237,7 @@ dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"time 0.1.43",
"winapi",
]
@ -1369,7 +1369,6 @@ dependencies = [
"base64",
"byteorder",
"bytes",
"chrono",
"dns-sd",
"env_logger",
"form_urlencoded",
@ -1400,6 +1399,7 @@ dependencies = [
"sha-1 0.10.0",
"shannon",
"thiserror",
"time 0.3.5",
"tokio",
"tokio-stream",
"tokio-tungstenite",
@ -1441,7 +1441,6 @@ dependencies = [
"async-trait",
"byteorder",
"bytes",
"chrono",
"librespot-core",
"librespot-protocol",
"log",
@ -2737,6 +2736,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "time"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad"
dependencies = [
"libc",
]
[[package]]
name = "tinyvec"
version = "1.5.1"

View file

@ -17,7 +17,6 @@ aes = "0.7"
base64 = "0.13"
byteorder = "1.4"
bytes = "1"
chrono = "0.4"
dns-sd = { version = "0.1", optional = true }
form_urlencoded = "1.0"
futures-core = "0.3"
@ -46,6 +45,7 @@ serde_json = "1.0"
sha-1 = "0.10"
shannon = "0.2"
thiserror = "1.0"
time = "0.3"
tokio = { version = "1", features = ["io-util", "macros", "net", "parking_lot", "rt", "sync", "time"] }
tokio-stream = "0.1"
tokio-tungstenite = { version = "*", default-features = false, features = ["rustls-tls-native-roots"] }

View file

@ -3,7 +3,6 @@ use std::{
ops::{Deref, DerefMut},
};
use chrono::Local;
use protobuf::Message;
use thiserror::Error;
use url::Url;
@ -84,9 +83,9 @@ impl CdnUrl {
return Err(CdnUrlError::Unresolved.into());
}
let now = Local::now();
let now = Date::now_utc();
let url = self.urls.iter().find(|url| match url.1 {
Some(expiry) => now < expiry.as_utc(),
Some(expiry) => now < expiry,
None => true,
});

View file

@ -1,30 +1,27 @@
use std::{convert::TryFrom, fmt::Debug, ops::Deref};
use std::{
convert::{TryFrom, TryInto},
fmt::Debug,
ops::Deref,
};
use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
use thiserror::Error;
use time::{error::ComponentRange, Date as _Date, OffsetDateTime, PrimitiveDateTime, Time};
use crate::Error;
use librespot_protocol as protocol;
use protocol::metadata::Date as DateMessage;
#[derive(Debug, Error)]
pub enum DateError {
#[error("item has invalid timestamp {0}")]
Timestamp(i64),
}
impl From<DateError> for Error {
fn from(err: DateError) -> Self {
Error::invalid_argument(err)
impl From<ComponentRange> for Error {
fn from(err: ComponentRange) -> Self {
Error::out_of_range(err)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Date(pub DateTime<Utc>);
pub struct Date(pub OffsetDateTime);
impl Deref for Date {
type Target = DateTime<Utc>;
type Target = OffsetDateTime;
fn deref(&self) -> &Self::Target {
&self.0
}
@ -32,42 +29,43 @@ impl Deref for Date {
impl Date {
pub fn as_timestamp(&self) -> i64 {
self.0.timestamp()
self.0.unix_timestamp()
}
pub fn from_timestamp(timestamp: i64) -> Result<Self, Error> {
if let Some(date_time) = NaiveDateTime::from_timestamp_opt(timestamp, 0) {
Ok(Self::from_utc(date_time))
} else {
Err(DateError::Timestamp(timestamp).into())
}
let date_time = OffsetDateTime::from_unix_timestamp(timestamp)?;
Ok(Self(date_time))
}
pub fn as_utc(&self) -> DateTime<Utc> {
pub fn as_utc(&self) -> OffsetDateTime {
self.0
}
pub fn from_utc(date_time: NaiveDateTime) -> Self {
Self(DateTime::<Utc>::from_utc(date_time, Utc))
pub fn from_utc(date_time: PrimitiveDateTime) -> Self {
Self(date_time.assume_utc())
}
pub fn now_utc() -> Self {
Self(OffsetDateTime::now_utc())
}
}
impl From<&DateMessage> for Date {
fn from(date: &DateMessage) -> Self {
let naive_date = NaiveDate::from_ymd(
date.get_year() as i32,
date.get_month() as u32,
date.get_day() as u32,
);
let naive_time = NaiveTime::from_hms(date.get_hour() as u32, date.get_minute() as u32, 0);
let naive_datetime = NaiveDateTime::new(naive_date, naive_time);
Self(DateTime::<Utc>::from_utc(naive_datetime, Utc))
impl TryFrom<&DateMessage> for Date {
type Error = crate::Error;
fn try_from(msg: &DateMessage) -> Result<Self, Self::Error> {
let date = _Date::from_calendar_date(
msg.get_year(),
(msg.get_month() as u8).try_into()?,
msg.get_day() as u8,
)?;
let time = Time::from_hms(msg.get_hour() as u8, msg.get_minute() as u8, 0)?;
Ok(Self::from_utc(PrimitiveDateTime::new(date, time)))
}
}
impl From<DateTime<Utc>> for Date {
fn from(date: DateTime<Utc>) -> Self {
Self(date)
impl From<OffsetDateTime> for Date {
fn from(datetime: OffsetDateTime) -> Self {
Self(datetime)
}
}

View file

@ -11,7 +11,6 @@ edition = "2018"
async-trait = "0.1"
byteorder = "1"
bytes = "1"
chrono = "0.4"
log = "0.4"
protobuf = "2"
thiserror = "1"

View file

@ -101,7 +101,7 @@ impl TryFrom<&<Self as Metadata>::Message> for Album {
artists: album.get_artist().try_into()?,
album_type: album.get_field_type(),
label: album.get_label().to_owned(),
date: album.get_date().into(),
date: album.get_date().try_into()?,
popularity: album.get_popularity(),
genres: album.get_genre().to_vec(),
covers: album.get_cover().into(),
@ -111,12 +111,12 @@ impl TryFrom<&<Self as Metadata>::Message> for Album {
copyrights: album.get_copyright().into(),
restrictions: album.get_restriction().into(),
related: album.get_related().try_into()?,
sale_periods: album.get_sale_period().into(),
sale_periods: album.get_sale_period().try_into()?,
cover_group: album.get_cover_group().get_image().into(),
original_title: album.get_original_title().to_owned(),
version_title: album.get_version_title().to_owned(),
type_str: album.get_type_str().to_owned(),
availability: album.get_availability().into(),
availability: album.get_availability().try_into()?,
})
}
}

View file

@ -1,7 +1,5 @@
use std::fmt::Debug;
use chrono::Local;
use crate::{
availability::{AudioItemAvailability, Availabilities, UnavailabilityReason},
episode::Episode,
@ -12,7 +10,7 @@ use crate::{
use super::file::AudioFiles;
use librespot_core::{session::UserData, spotify_id::SpotifyItemType, Error, Session, SpotifyId};
use librespot_core::{session::UserData, date::Date, spotify_id::SpotifyItemType, Error, Session, SpotifyId};
pub type AudioItemResult = Result<AudioItem, Error>;
@ -93,7 +91,7 @@ pub trait InnerAudioItem {
if !(availability
.iter()
.any(|availability| Local::now() >= availability.start.as_utc()))
.any(|availability| Date::now_utc() >= availability.start))
{
return Err(UnavailabilityReason::Embargo);
}

View file

@ -1,8 +1,8 @@
use std::{fmt::Debug, ops::Deref};
use std::{convert::{TryFrom, TryInto}, fmt::Debug, ops::Deref};
use thiserror::Error;
use crate::util::from_repeated_message;
use crate::util::try_from_repeated_message;
use librespot_core::date::Date;
@ -39,13 +39,14 @@ pub enum UnavailabilityReason {
NotWhitelisted,
}
impl From<&AvailabilityMessage> for Availability {
fn from(availability: &AvailabilityMessage) -> Self {
Self {
impl TryFrom<&AvailabilityMessage> for Availability {
type Error = librespot_core::Error;
fn try_from(availability: &AvailabilityMessage) -> Result<Self, Self::Error> {
Ok(Self {
catalogue_strs: availability.get_catalogue_str().to_vec(),
start: availability.get_start().into(),
}
start: availability.get_start().try_into()?,
})
}
}
from_repeated_message!(AvailabilityMessage, Availabilities);
try_from_repeated_message!(AvailabilityMessage, Availabilities);

View file

@ -108,7 +108,7 @@ impl TryFrom<&<Self as Metadata>::Message> for Episode {
audio: episode.get_audio().into(),
description: episode.get_description().to_owned(),
number: episode.get_number(),
publish_time: episode.get_publish_time().into(),
publish_time: episode.get_publish_time().try_into()?,
covers: episode.get_cover_image().get_image().into(),
language: episode.get_language().to_owned(),
is_explicit: episode.get_explicit().to_owned(),
@ -120,7 +120,7 @@ impl TryFrom<&<Self as Metadata>::Message> for Episode {
freeze_frames: episode.get_freeze_frame().get_image().into(),
keywords: episode.get_keyword().to_vec(),
allow_background_playback: episode.get_allow_background_playback(),
availability: episode.get_availability().into(),
availability: episode.get_availability().try_into()?,
external_url: episode.get_external_url().to_owned(),
episode_type: episode.get_field_type(),
has_music_and_talk: episode.get_music_and_talk(),

View file

@ -1,6 +1,6 @@
use std::{fmt::Debug, ops::Deref};
use std::{convert::{TryFrom, TryInto}, fmt::Debug, ops::Deref};
use crate::{restriction::Restrictions, util::from_repeated_message};
use crate::{restriction::Restrictions, util::try_from_repeated_message};
use librespot_core::date::Date;
@ -24,14 +24,15 @@ impl Deref for SalePeriods {
}
}
impl From<&SalePeriodMessage> for SalePeriod {
fn from(sale_period: &SalePeriodMessage) -> Self {
Self {
impl TryFrom<&SalePeriodMessage> for SalePeriod {
type Error = librespot_core::Error;
fn try_from(sale_period: &SalePeriodMessage) -> Result<Self, Self::Error> {
Ok(Self {
restrictions: sale_period.get_restriction().into(),
start: sale_period.get_start().into(),
end: sale_period.get_end().into(),
}
start: sale_period.get_start().try_into()?,
end: sale_period.get_end().try_into()?,
})
}
}
from_repeated_message!(SalePeriodMessage, SalePeriods);
try_from_repeated_message!(SalePeriodMessage, SalePeriods);

View file

@ -65,7 +65,7 @@ impl TryFrom<&<Self as Metadata>::Message> for Show {
keywords: show.get_keyword().to_vec(),
media_type: show.get_media_type(),
consumption_order: show.get_consumption_order(),
availability: show.get_availability().into(),
availability: show.get_availability().try_into()?,
trailer_uri: SpotifyId::from_uri(show.get_trailer_uri())?,
has_music_and_talk: show.get_music_and_talk(),
is_audiobook: show.get_is_audiobook(),

View file

@ -4,7 +4,6 @@ use std::{
ops::Deref,
};
use chrono::Local;
use uuid::Uuid;
use crate::{
@ -77,7 +76,7 @@ impl InnerAudioItem for Track {
};
// TODO: check meaning of earliest_live_timestamp in
let availability = if Local::now() < track.earliest_live_timestamp.as_utc() {
let availability = if Date::now_utc() < track.earliest_live_timestamp {
Err(UnavailabilityReason::Embargo)
} else {
Self::available_for_user(
@ -130,12 +129,12 @@ impl TryFrom<&<Self as Metadata>::Message> for Track {
restrictions: track.get_restriction().into(),
files: track.get_file().into(),
alternatives: track.get_alternative().try_into()?,
sale_periods: track.get_sale_period().into(),
sale_periods: track.get_sale_period().try_into()?,
previews: track.get_preview().into(),
tags: track.get_tags().to_vec(),
earliest_live_timestamp: track.get_earliest_live_timestamp().try_into()?,
has_lyrics: track.get_has_lyrics(),
availability: track.get_availability().into(),
availability: track.get_availability().try_into()?,
licensor: Uuid::from_slice(track.get_licensor().get_uuid())
.unwrap_or_else(|_| Uuid::nil()),
language_of_performance: track.get_language_of_performance().to_vec(),