From 06680f106cdd684c4671a1fbbd8d1420ace1d01d Mon Sep 17 00:00:00 2001 From: ashthespy Date: Tue, 16 Jul 2019 19:36:20 +0200 Subject: [PATCH 1/8] Add `pkg-config` to docker build container --- contrib/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/Dockerfile b/contrib/Dockerfile index 0fcdafff..9cf2d134 100644 --- a/contrib/Dockerfile +++ b/contrib/Dockerfile @@ -21,7 +21,7 @@ RUN dpkg --add-architecture armel RUN dpkg --add-architecture mipsel RUN apt-get update -RUN apt-get install -y curl git build-essential crossbuild-essential-arm64 crossbuild-essential-armel crossbuild-essential-armhf crossbuild-essential-mipsel +RUN apt-get install -y curl git build-essential crossbuild-essential-arm64 crossbuild-essential-armel crossbuild-essential-armhf crossbuild-essential-mipsel pkg-config RUN apt-get install -y libasound2-dev libasound2-dev:arm64 libasound2-dev:armel libasound2-dev:armhf libasound2-dev:mipsel RUN curl https://sh.rustup.rs -sSf | sh -s -- -y @@ -43,6 +43,7 @@ RUN mkdir /build && \ ENV CARGO_TARGET_DIR /build ENV CARGO_HOME /build/cache +ENV PKG_CONFIG_ALLOW_CROSS=1 ADD . /src WORKDIR /src From 0cb7a3f7c85b3d7baf5d0d80dea14d0172062caf Mon Sep 17 00:00:00 2001 From: ashthespy Date: Fri, 28 Sep 2018 20:10:22 +0200 Subject: [PATCH 2/8] WIP: Podcast support --- connect/src/spirc.rs | 11 +- core/src/spotify_id.rs | 44 +- metadata/src/lib.rs | 107 ++ playback/src/player.rs | 99 +- protocol/files.rs | 9 + protocol/proto/metadata.proto | 79 +- protocol/src/metadata.rs | 2780 ++++++++++++++++++++++++++++++++- 7 files changed, 3073 insertions(+), 56 deletions(-) create mode 100644 protocol/files.rs diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 37576a9e..92e26ce0 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -168,6 +168,7 @@ fn initial_device_state(config: ConnectConfig) -> DeviceState { let repeated = msg.mut_stringValue(); repeated.push(::std::convert::Into::into("audio/local")); repeated.push(::std::convert::Into::into("audio/track")); + repeated.push(::std::convert::Into::into("audio/episode")); repeated.push(::std::convert::Into::into("local")); repeated.push(::std::convert::Into::into("track")) }; @@ -796,6 +797,7 @@ impl SpircTask { } fn update_tracks(&mut self, frame: &protocol::spirc::Frame) { + // debug!("State: {:?}", frame.get_state()); let index = frame.get_state().get_playing_track_index(); let context_uri = frame.get_state().get_context_uri().to_owned(); let tracks = frame.get_state().get_track(); @@ -812,7 +814,14 @@ impl SpircTask { } fn load_track(&mut self, play: bool) { - let track = { + let context_uri = self.state.get_context_uri().to_owned(); + let index = self.state.get_playing_track_index(); + info!("context: {}", context_uri); + // Redundant check here + let track = if context_uri.contains(":show:") || context_uri.contains(":episode:") { + let uri = self.state.get_track()[index as usize].get_uri(); + SpotifyId::from_uri(uri).expect("Unable to parse uri") + } else { let mut index = self.state.get_playing_track_index(); // Check for malformed gid let tracks_len = self.state.get_track().len() as u32; diff --git a/core/src/spotify_id.rs b/core/src/spotify_id.rs index 79414a18..01c4ddd4 100644 --- a/core/src/spotify_id.rs +++ b/core/src/spotify_id.rs @@ -1,8 +1,17 @@ use std; use std::fmt; -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct SpotifyId(u128); +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum SpotifyTrackType { + Track, + Podcast, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct SpotifyId { + pub id: u128, + pub track_type: SpotifyTrackType, +} #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct SpotifyIdError; @@ -11,6 +20,13 @@ const BASE62_DIGITS: &'static [u8] = b"0123456789abcdefghijklmnopqrstuvwxyzABCDE const BASE16_DIGITS: &'static [u8] = b"0123456789abcdef"; impl SpotifyId { + fn as_track(n: u128) -> SpotifyId { + SpotifyId { + id: n.to_owned(), + track_type: SpotifyTrackType::Track, + } + } + pub fn from_base16(id: &str) -> Result { let data = id.as_bytes(); @@ -24,7 +40,7 @@ impl SpotifyId { n = n + d; } - Ok(SpotifyId(n)) + Ok(SpotifyId::as_track(n)) } pub fn from_base62(id: &str) -> Result { @@ -39,8 +55,7 @@ impl SpotifyId { n = n * 62; n = n + d; } - - Ok(SpotifyId(n)) + Ok(SpotifyId::as_track(n)) } pub fn from_raw(data: &[u8]) -> Result { @@ -51,15 +66,26 @@ impl SpotifyId { let mut arr: [u8; 16] = Default::default(); arr.copy_from_slice(&data[0..16]); - Ok(SpotifyId(u128::from_be_bytes(arr))) + Ok(SpotifyId::as_track(u128::from_be_bytes(arr))) + } + + pub fn from_uri(uri: &str) -> Result { + let parts = uri.split(":").collect::>(); + if uri.contains(":show:") || uri.contains(":episode:") { + let mut spotify_id = SpotifyId::from_base62(parts[2]).unwrap(); + spotify_id.track_type = SpotifyTrackType::Podcast; + Ok(spotify_id) + } else { + SpotifyId::from_base62(parts[2]) + } } pub fn to_base16(&self) -> String { - format!("{:032x}", self.0) + format!("{:032x}", self.id) } pub fn to_base62(&self) -> String { - let &SpotifyId(mut n) = self; + let &SpotifyId { id: mut n, .. } = self; let mut data = [0u8; 22]; for i in 0..22 { @@ -71,7 +97,7 @@ impl SpotifyId { } pub fn to_raw(&self) -> [u8; 16] { - self.0.to_be_bytes() + self.id.to_be_bytes() } } diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 60ca2738..6aa6a5bd 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -93,6 +93,28 @@ pub struct Album { pub covers: Vec, } +#[derive(Debug, Clone)] +pub struct Episode { + pub id: SpotifyId, + pub name: String, + pub external_url: String, + pub duration: i32, + pub language: String, + pub show: SpotifyId, + pub files: LinearMap, + pub covers: Vec, + pub available: bool, + pub explicit: bool, +} + +#[derive(Debug, Clone)] +pub struct Show { + pub id: SpotifyId, + pub name: String, + pub episodes: Vec, + pub covers: Vec, +} + #[derive(Debug, Clone)] pub struct Artist { pub id: SpotifyId, @@ -222,6 +244,91 @@ impl Metadata for Artist { } } +// Podcast +impl Metadata for Episode { + type Message = protocol::metadata::Episode; + + fn base_url() -> &'static str { + "hm://metadata/3/episode" + } + + fn parse(msg: &Self::Message, session: &Session) -> Self { + let country = session.country(); + + let files = msg + .get_file() + .iter() + .filter(|file| file.has_file_id()) + .map(|file| { + let mut dst = [0u8; 20]; + dst.clone_from_slice(file.get_file_id()); + (file.get_format(), FileId(dst)) + }) + .collect(); + + let covers = msg + .get_covers() + .get_image() + .iter() + .filter(|image| image.has_file_id()) + .map(|image| { + let mut dst = [0u8; 20]; + dst.clone_from_slice(image.get_file_id()); + FileId(dst) + }) + .collect::>(); + + Episode { + id: SpotifyId::from_raw(msg.get_gid()).unwrap(), + name: msg.get_name().to_owned(), + external_url: msg.get_external_url().to_owned(), + duration: msg.get_duration().to_owned(), + language: msg.get_language().to_owned(), + show: SpotifyId::from_raw(msg.get_show().get_gid()).unwrap(), + covers: covers, + files: files, + available: parse_restrictions(msg.get_restriction(), &country, "premium"), + explicit: msg.get_explicit().to_owned(), + } + } +} + +impl Metadata for Show { + type Message = protocol::metadata::Show; + + fn base_url() -> &'static str { + "hm://metadata/3/show" + } + + fn parse(msg: &Self::Message, _: &Session) -> Self { + let episodes = msg + .get_episode() + .iter() + .filter(|episode| episode.has_gid()) + .map(|episode| SpotifyId::from_raw(episode.get_gid()).unwrap()) + .collect::>(); + + let covers = msg + .get_covers() + .get_image() + .iter() + .filter(|image| image.has_file_id()) + .map(|image| { + let mut dst = [0u8; 20]; + dst.clone_from_slice(image.get_file_id()); + FileId(dst) + }) + .collect::>(); + + Show { + id: SpotifyId::from_raw(msg.get_gid()).unwrap(), + name: msg.get_name().to_owned(), + episodes: episodes, + covers: covers, + } + } +} + struct StrChunks<'s>(&'s str, usize); trait StrChunksExt { diff --git a/playback/src/player.rs b/playback/src/player.rs index 4be73acd..3b48a594 100644 --- a/playback/src/player.rs +++ b/playback/src/player.rs @@ -12,12 +12,12 @@ use std::time::Duration; use config::{Bitrate, PlayerConfig}; use librespot_core::session::Session; -use librespot_core::spotify_id::SpotifyId; +use librespot_core::spotify_id::{FileId, SpotifyId, SpotifyTrackType}; use audio::{AudioDecrypt, AudioFile}; use audio::{VorbisDecoder, VorbisPacket}; use audio_backend::Sink; -use metadata::{FileFormat, Metadata, Track}; +use metadata::{Episode, FileFormat, Metadata, Track}; use mixer::AudioFilter; pub struct Player { @@ -526,44 +526,77 @@ impl PlayerInternal { } } - fn load_track(&self, track_id: SpotifyId, position: i64) -> Option<(Decoder, f32)> { - let track = Track::get(&self.session, track_id).wait().unwrap(); + fn get_file_id(&self, spotify_id: SpotifyId) -> Option { + let file_id = match spotify_id.track_type { + SpotifyTrackType::Track => { + let track = Track::get(&self.session, spotify_id).wait().unwrap(); - info!( - "Loading track \"{}\" with Spotify URI \"spotify:track:{}\"", - track.name, - track_id.to_base62() - ); + info!( + "Loading track \"{}\" with Spotify URI \"spotify:track:{}\"", + track.name, + spotify_id.to_base62() + ); - let track = match self.find_available_alternative(&track) { - Some(track) => track, - None => { - warn!("Track \"{}\" is not available", track.name); - return None; + let track = match self.find_available_alternative(&track) { + Some(track) => track, + None => { + warn!("Track \"{}\" is not available", track.name); + return None; + } + }; + + let format = match self.config.bitrate { + Bitrate::Bitrate96 => FileFormat::OGG_VORBIS_96, + Bitrate::Bitrate160 => FileFormat::OGG_VORBIS_160, + Bitrate::Bitrate320 => FileFormat::OGG_VORBIS_320, + }; + match track.files.get(&format) { + Some(&file_id) => file_id, + None => { + warn!("Track \"{}\" is not available in format {:?}", track.name, format); + return None; + } + } + } + // This should be refactored! + SpotifyTrackType::Podcast => { + let episode = Episode::get(&self.session, spotify_id).wait().unwrap(); + info!("Episode {:?}", episode); + + info!( + "Loading episode \"{}\" with Spotify URI \"spotify:episode:{}\"", + episode.name, + spotify_id.to_base62() + ); + + // Podcasts seem to have only 96 OGG_VORBIS support, other filetypes indicate + // AAC_24, MP4_128, MP4_128_DUAL, MP3_96 among others + let format = match self.config.bitrate { + _ => FileFormat::OGG_VORBIS_96, + }; + + match episode.files.get(&format) { + Some(&file_id) => file_id, + None => { + warn!( + "Episode \"{}\" is not available in format {:?}", + episode.name, format + ); + return None; + } + } } }; + return Some(file_id); + } - let format = match self.config.bitrate { - Bitrate::Bitrate96 => FileFormat::OGG_VORBIS_96, - Bitrate::Bitrate160 => FileFormat::OGG_VORBIS_160, - Bitrate::Bitrate320 => FileFormat::OGG_VORBIS_320, - }; + fn load_track(&self, spotify_id: SpotifyId, position: i64) -> Option<(Decoder, f32)> { + let file_id = self.get_file_id(spotify_id).unwrap(); + info!("{:?} -> {:?}", spotify_id, file_id); - let file_id = match track.files.get(&format) { - Some(&file_id) => file_id, - None => { - warn!("Track \"{}\" is not available in format {:?}", track.name, format); - return None; - } - }; - - let key = self - .session - .audio_key() - .request(track.id, file_id); + let key = self.session.audio_key().request(spotify_id, file_id); let encrypted_file = AudioFile::open(&self.session, file_id); - let encrypted_file = encrypted_file.wait().unwrap(); let key = key.wait().unwrap(); let mut decrypted_file = AudioDecrypt::new(key, encrypted_file); @@ -587,7 +620,7 @@ impl PlayerInternal { } } - info!("Track \"{}\" loaded", track.name); + // info!("Track \"{}\" loaded", track.name); Some((decoder, normalisation_factor)) } diff --git a/protocol/files.rs b/protocol/files.rs new file mode 100644 index 00000000..f4ddd9ad --- /dev/null +++ b/protocol/files.rs @@ -0,0 +1,9 @@ +// Autogenerated by build.rs +pub const FILES: &'static [(&'static str, u32)] = &[ + ("proto/authentication.proto", 2098196376), + ("proto/keyexchange.proto", 451735664), + ("proto/mercury.proto", 709993906), + ("proto/metadata.proto", 1409162985), + ("proto/pubsub.proto", 2686584829), + ("proto/spirc.proto", 1587493382), +]; diff --git a/protocol/proto/metadata.proto b/protocol/proto/metadata.proto index 1a7a900b..c3730ca7 100644 --- a/protocol/proto/metadata.proto +++ b/protocol/proto/metadata.proto @@ -156,12 +156,87 @@ message AudioFile { MP3_160 = 0x5; MP3_96 = 0x6; MP3_160_ENC = 0x7; - OTHER2 = 0x8; + MP4_128_DUAL = 0x8; OTHER3 = 0x9; AAC_160 = 0xa; AAC_320 = 0xb; - OTHER4 = 0xc; + MP4_128 = 0xc; OTHER5 = 0xd; } } +// Podcast Protos +message PublishTime { + optional sint32 year = 0x1; + optional sint32 month = 0x2; + optional sint32 day = 0x3; + // These seem to be differently encoded + optional sint32 minute = 0x5; + optional sint32 hour = 0x4; +} + +message Show { + optional bytes gid = 0x1; + optional string name = 0x2; + repeated Episode episode = 0x46; + // Educated guesses + optional string description = 0x40; + optional string publisher = 0x42; + optional string language = 0x43; + optional bool explicit = 0x44; + optional ImageGroup covers = 0x45; + repeated Restriction restriction = 0x48; + optional MediaType media_type = 0x4A; + optional ConsumptionOrder consumption_order = 0x4B; + optional bool interpret_restriction_using_geoip = 0x4C; + optional string country_of_origin = 0x4F; + repeated Category categories = 0x50; + optional PassthroughEnum passthrough = 0x51; +} + +enum ConsumptionOrder { + SEQUENTIAL = 1; + EPISODIC = 2; + RECENT = 3; + } +enum MediaType { + MIXED = 0; + AUDIO = 1; + VIDEO = 2; +} +enum PassthroughEnum { + UNKNOWN = 0; + NONE = 1; +} + +message Episode { + optional bytes gid = 0x1; + optional string name = 0x2; + optional sint32 duration = 0x7; + optional sint32 popularity = 0x8; + repeated AudioFile file = 0xc; + // Educated guesses + optional string description = 0x40; + optional Date publish_time = 0x42; + optional ImageGroup covers = 0x44; + optional string language = 0x45; + optional bool explicit = 0x46; + optional Show show = 0x47; + repeated AudioFile preview = 0x4A; + repeated Restriction restriction = 0x4B; + // Order of these flags might be wrong! + optional bool suppress_monetization = 0x4E; + optional bool allow_background_playback = 0x4F; + optional bool interpret_restriction_using_geoip = 0x51; + optional string external_url = 0x53; + optional OriginalAudio original_audio = 0x54; +} + +message Category { + optional string name = 0x1; + repeated Category subcategories = 0x2; +} + +message OriginalAudio { + optional bytes uuid = 0x1; +} diff --git a/protocol/src/metadata.rs b/protocol/src/metadata.rs index 7cfa964d..1a1a7f00 100644 --- a/protocol/src/metadata.rs +++ b/protocol/src/metadata.rs @@ -6143,11 +6143,11 @@ pub enum AudioFile_Format { MP3_160 = 5, MP3_96 = 6, MP3_160_ENC = 7, - OTHER2 = 8, + MP4_128_DUAL = 8, OTHER3 = 9, AAC_160 = 10, AAC_320 = 11, - OTHER4 = 12, + MP4_128 = 12, OTHER5 = 13, } @@ -6166,11 +6166,11 @@ impl ::protobuf::ProtobufEnum for AudioFile_Format { 5 => ::std::option::Option::Some(AudioFile_Format::MP3_160), 6 => ::std::option::Option::Some(AudioFile_Format::MP3_96), 7 => ::std::option::Option::Some(AudioFile_Format::MP3_160_ENC), - 8 => ::std::option::Option::Some(AudioFile_Format::OTHER2), + 8 => ::std::option::Option::Some(AudioFile_Format::MP4_128_DUAL), 9 => ::std::option::Option::Some(AudioFile_Format::OTHER3), 10 => ::std::option::Option::Some(AudioFile_Format::AAC_160), 11 => ::std::option::Option::Some(AudioFile_Format::AAC_320), - 12 => ::std::option::Option::Some(AudioFile_Format::OTHER4), + 12 => ::std::option::Option::Some(AudioFile_Format::MP4_128), 13 => ::std::option::Option::Some(AudioFile_Format::OTHER5), _ => ::std::option::Option::None } @@ -6186,11 +6186,11 @@ impl ::protobuf::ProtobufEnum for AudioFile_Format { AudioFile_Format::MP3_160, AudioFile_Format::MP3_96, AudioFile_Format::MP3_160_ENC, - AudioFile_Format::OTHER2, + AudioFile_Format::MP4_128_DUAL, AudioFile_Format::OTHER3, AudioFile_Format::AAC_160, AudioFile_Format::AAC_320, - AudioFile_Format::OTHER4, + AudioFile_Format::MP4_128, AudioFile_Format::OTHER5, ]; values @@ -6224,6 +6224,2729 @@ impl ::protobuf::reflect::ProtobufValue for AudioFile_Format { } } +#[derive(PartialEq,Clone,Default)] +pub struct PublishTime { + // message fields + year: ::std::option::Option, + month: ::std::option::Option, + day: ::std::option::Option, + minute: ::std::option::Option, + hour: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a PublishTime { + fn default() -> &'a PublishTime { + ::default_instance() + } +} + +impl PublishTime { + pub fn new() -> PublishTime { + ::std::default::Default::default() + } + + // optional sint32 year = 1; + + + pub fn get_year(&self) -> i32 { + self.year.unwrap_or(0) + } + pub fn clear_year(&mut self) { + self.year = ::std::option::Option::None; + } + + pub fn has_year(&self) -> bool { + self.year.is_some() + } + + // Param is passed by value, moved + pub fn set_year(&mut self, v: i32) { + self.year = ::std::option::Option::Some(v); + } + + // optional sint32 month = 2; + + + pub fn get_month(&self) -> i32 { + self.month.unwrap_or(0) + } + pub fn clear_month(&mut self) { + self.month = ::std::option::Option::None; + } + + pub fn has_month(&self) -> bool { + self.month.is_some() + } + + // Param is passed by value, moved + pub fn set_month(&mut self, v: i32) { + self.month = ::std::option::Option::Some(v); + } + + // optional sint32 day = 3; + + + pub fn get_day(&self) -> i32 { + self.day.unwrap_or(0) + } + pub fn clear_day(&mut self) { + self.day = ::std::option::Option::None; + } + + pub fn has_day(&self) -> bool { + self.day.is_some() + } + + // Param is passed by value, moved + pub fn set_day(&mut self, v: i32) { + self.day = ::std::option::Option::Some(v); + } + + // optional sint32 minute = 5; + + + pub fn get_minute(&self) -> i32 { + self.minute.unwrap_or(0) + } + pub fn clear_minute(&mut self) { + self.minute = ::std::option::Option::None; + } + + pub fn has_minute(&self) -> bool { + self.minute.is_some() + } + + // Param is passed by value, moved + pub fn set_minute(&mut self, v: i32) { + self.minute = ::std::option::Option::Some(v); + } + + // optional sint32 hour = 4; + + + pub fn get_hour(&self) -> i32 { + self.hour.unwrap_or(0) + } + pub fn clear_hour(&mut self) { + self.hour = ::std::option::Option::None; + } + + pub fn has_hour(&self) -> bool { + self.hour.is_some() + } + + // Param is passed by value, moved + pub fn set_hour(&mut self, v: i32) { + self.hour = ::std::option::Option::Some(v); + } +} + +impl ::protobuf::Message for PublishTime { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.year = ::std::option::Option::Some(tmp); + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.month = ::std::option::Option::Some(tmp); + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.day = ::std::option::Option::Some(tmp); + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.minute = ::std::option::Option::Some(tmp); + }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.hour = ::std::option::Option::Some(tmp); + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(v) = self.year { + my_size += ::protobuf::rt::value_varint_zigzag_size(1, v); + } + if let Some(v) = self.month { + my_size += ::protobuf::rt::value_varint_zigzag_size(2, v); + } + if let Some(v) = self.day { + my_size += ::protobuf::rt::value_varint_zigzag_size(3, v); + } + if let Some(v) = self.minute { + my_size += ::protobuf::rt::value_varint_zigzag_size(5, v); + } + if let Some(v) = self.hour { + my_size += ::protobuf::rt::value_varint_zigzag_size(4, v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + if let Some(v) = self.year { + os.write_sint32(1, v)?; + } + if let Some(v) = self.month { + os.write_sint32(2, v)?; + } + if let Some(v) = self.day { + os.write_sint32(3, v)?; + } + if let Some(v) = self.minute { + os.write_sint32(5, v)?; + } + if let Some(v) = self.hour { + os.write_sint32(4, v)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> PublishTime { + PublishTime::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, + }; + unsafe { + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "year", + |m: &PublishTime| { &m.year }, + |m: &mut PublishTime| { &mut m.year }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "month", + |m: &PublishTime| { &m.month }, + |m: &mut PublishTime| { &mut m.month }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "day", + |m: &PublishTime| { &m.day }, + |m: &mut PublishTime| { &mut m.day }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "minute", + |m: &PublishTime| { &m.minute }, + |m: &mut PublishTime| { &mut m.minute }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "hour", + |m: &PublishTime| { &m.hour }, + |m: &mut PublishTime| { &mut m.hour }, + )); + ::protobuf::reflect::MessageDescriptor::new::( + "PublishTime", + fields, + file_descriptor_proto() + ) + }) + } + } + + fn default_instance() -> &'static PublishTime { + static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const PublishTime, + }; + unsafe { + instance.get(PublishTime::new) + } + } +} + +impl ::protobuf::Clear for PublishTime { + fn clear(&mut self) { + self.year = ::std::option::Option::None; + self.month = ::std::option::Option::None; + self.day = ::std::option::Option::None; + self.minute = ::std::option::Option::None; + self.hour = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for PublishTime { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for PublishTime { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Show { + // message fields + gid: ::protobuf::SingularField<::std::vec::Vec>, + name: ::protobuf::SingularField<::std::string::String>, + episode: ::protobuf::RepeatedField, + description: ::protobuf::SingularField<::std::string::String>, + publisher: ::protobuf::SingularField<::std::string::String>, + language: ::protobuf::SingularField<::std::string::String>, + explicit: ::std::option::Option, + covers: ::protobuf::SingularPtrField, + restriction: ::protobuf::RepeatedField, + media_type: ::std::option::Option, + consumption_order: ::std::option::Option, + interpret_restriction_using_geoip: ::std::option::Option, + country_of_origin: ::protobuf::SingularField<::std::string::String>, + categories: ::protobuf::RepeatedField, + passthrough: ::std::option::Option, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Show { + fn default() -> &'a Show { + ::default_instance() + } +} + +impl Show { + pub fn new() -> Show { + ::std::default::Default::default() + } + + // optional bytes gid = 1; + + + pub fn get_gid(&self) -> &[u8] { + match self.gid.as_ref() { + Some(v) => &v, + None => &[], + } + } + pub fn clear_gid(&mut self) { + self.gid.clear(); + } + + pub fn has_gid(&self) -> bool { + self.gid.is_some() + } + + // Param is passed by value, moved + pub fn set_gid(&mut self, v: ::std::vec::Vec) { + self.gid = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_gid(&mut self) -> &mut ::std::vec::Vec { + if self.gid.is_none() { + self.gid.set_default(); + } + self.gid.as_mut().unwrap() + } + + // Take field + pub fn take_gid(&mut self) -> ::std::vec::Vec { + self.gid.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // optional string name = 2; + + + pub fn get_name(&self) -> &str { + match self.name.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + pub fn has_name(&self) -> bool { + self.name.is_some() + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + if self.name.is_none() { + self.name.set_default(); + } + self.name.as_mut().unwrap() + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + self.name.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // repeated .Episode episode = 70; + + + pub fn get_episode(&self) -> &[Episode] { + &self.episode + } + pub fn clear_episode(&mut self) { + self.episode.clear(); + } + + // Param is passed by value, moved + pub fn set_episode(&mut self, v: ::protobuf::RepeatedField) { + self.episode = v; + } + + // Mutable pointer to the field. + pub fn mut_episode(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.episode + } + + // Take field + pub fn take_episode(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.episode, ::protobuf::RepeatedField::new()) + } + + // optional string description = 64; + + + pub fn get_description(&self) -> &str { + match self.description.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_description(&mut self) { + self.description.clear(); + } + + pub fn has_description(&self) -> bool { + self.description.is_some() + } + + // Param is passed by value, moved + pub fn set_description(&mut self, v: ::std::string::String) { + self.description = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_description(&mut self) -> &mut ::std::string::String { + if self.description.is_none() { + self.description.set_default(); + } + self.description.as_mut().unwrap() + } + + // Take field + pub fn take_description(&mut self) -> ::std::string::String { + self.description.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // optional string publisher = 66; + + + pub fn get_publisher(&self) -> &str { + match self.publisher.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_publisher(&mut self) { + self.publisher.clear(); + } + + pub fn has_publisher(&self) -> bool { + self.publisher.is_some() + } + + // Param is passed by value, moved + pub fn set_publisher(&mut self, v: ::std::string::String) { + self.publisher = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_publisher(&mut self) -> &mut ::std::string::String { + if self.publisher.is_none() { + self.publisher.set_default(); + } + self.publisher.as_mut().unwrap() + } + + // Take field + pub fn take_publisher(&mut self) -> ::std::string::String { + self.publisher.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // optional string language = 67; + + + pub fn get_language(&self) -> &str { + match self.language.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_language(&mut self) { + self.language.clear(); + } + + pub fn has_language(&self) -> bool { + self.language.is_some() + } + + // Param is passed by value, moved + pub fn set_language(&mut self, v: ::std::string::String) { + self.language = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_language(&mut self) -> &mut ::std::string::String { + if self.language.is_none() { + self.language.set_default(); + } + self.language.as_mut().unwrap() + } + + // Take field + pub fn take_language(&mut self) -> ::std::string::String { + self.language.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // optional bool explicit = 68; + + + pub fn get_explicit(&self) -> bool { + self.explicit.unwrap_or(false) + } + pub fn clear_explicit(&mut self) { + self.explicit = ::std::option::Option::None; + } + + pub fn has_explicit(&self) -> bool { + self.explicit.is_some() + } + + // Param is passed by value, moved + pub fn set_explicit(&mut self, v: bool) { + self.explicit = ::std::option::Option::Some(v); + } + + // optional .ImageGroup covers = 69; + + + pub fn get_covers(&self) -> &ImageGroup { + self.covers.as_ref().unwrap_or_else(|| ImageGroup::default_instance()) + } + pub fn clear_covers(&mut self) { + self.covers.clear(); + } + + pub fn has_covers(&self) -> bool { + self.covers.is_some() + } + + // Param is passed by value, moved + pub fn set_covers(&mut self, v: ImageGroup) { + self.covers = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_covers(&mut self) -> &mut ImageGroup { + if self.covers.is_none() { + self.covers.set_default(); + } + self.covers.as_mut().unwrap() + } + + // Take field + pub fn take_covers(&mut self) -> ImageGroup { + self.covers.take().unwrap_or_else(|| ImageGroup::new()) + } + + // repeated .Restriction restriction = 72; + + + pub fn get_restriction(&self) -> &[Restriction] { + &self.restriction + } + pub fn clear_restriction(&mut self) { + self.restriction.clear(); + } + + // Param is passed by value, moved + pub fn set_restriction(&mut self, v: ::protobuf::RepeatedField) { + self.restriction = v; + } + + // Mutable pointer to the field. + pub fn mut_restriction(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.restriction + } + + // Take field + pub fn take_restriction(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.restriction, ::protobuf::RepeatedField::new()) + } + + // optional .MediaType media_type = 74; + + + pub fn get_media_type(&self) -> MediaType { + self.media_type.unwrap_or(MediaType::MIXED) + } + pub fn clear_media_type(&mut self) { + self.media_type = ::std::option::Option::None; + } + + pub fn has_media_type(&self) -> bool { + self.media_type.is_some() + } + + // Param is passed by value, moved + pub fn set_media_type(&mut self, v: MediaType) { + self.media_type = ::std::option::Option::Some(v); + } + + // optional .ConsumptionOrder consumption_order = 75; + + + pub fn get_consumption_order(&self) -> ConsumptionOrder { + self.consumption_order.unwrap_or(ConsumptionOrder::SEQUENTIAL) + } + pub fn clear_consumption_order(&mut self) { + self.consumption_order = ::std::option::Option::None; + } + + pub fn has_consumption_order(&self) -> bool { + self.consumption_order.is_some() + } + + // Param is passed by value, moved + pub fn set_consumption_order(&mut self, v: ConsumptionOrder) { + self.consumption_order = ::std::option::Option::Some(v); + } + + // optional bool interpret_restriction_using_geoip = 76; + + + pub fn get_interpret_restriction_using_geoip(&self) -> bool { + self.interpret_restriction_using_geoip.unwrap_or(false) + } + pub fn clear_interpret_restriction_using_geoip(&mut self) { + self.interpret_restriction_using_geoip = ::std::option::Option::None; + } + + pub fn has_interpret_restriction_using_geoip(&self) -> bool { + self.interpret_restriction_using_geoip.is_some() + } + + // Param is passed by value, moved + pub fn set_interpret_restriction_using_geoip(&mut self, v: bool) { + self.interpret_restriction_using_geoip = ::std::option::Option::Some(v); + } + + // optional string country_of_origin = 79; + + + pub fn get_country_of_origin(&self) -> &str { + match self.country_of_origin.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_country_of_origin(&mut self) { + self.country_of_origin.clear(); + } + + pub fn has_country_of_origin(&self) -> bool { + self.country_of_origin.is_some() + } + + // Param is passed by value, moved + pub fn set_country_of_origin(&mut self, v: ::std::string::String) { + self.country_of_origin = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_country_of_origin(&mut self) -> &mut ::std::string::String { + if self.country_of_origin.is_none() { + self.country_of_origin.set_default(); + } + self.country_of_origin.as_mut().unwrap() + } + + // Take field + pub fn take_country_of_origin(&mut self) -> ::std::string::String { + self.country_of_origin.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // repeated .Category categories = 80; + + + pub fn get_categories(&self) -> &[Category] { + &self.categories + } + pub fn clear_categories(&mut self) { + self.categories.clear(); + } + + // Param is passed by value, moved + pub fn set_categories(&mut self, v: ::protobuf::RepeatedField) { + self.categories = v; + } + + // Mutable pointer to the field. + pub fn mut_categories(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.categories + } + + // Take field + pub fn take_categories(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.categories, ::protobuf::RepeatedField::new()) + } + + // optional .PassthroughEnum passthrough = 81; + + + pub fn get_passthrough(&self) -> PassthroughEnum { + self.passthrough.unwrap_or(PassthroughEnum::UNKNOWN) + } + pub fn clear_passthrough(&mut self) { + self.passthrough = ::std::option::Option::None; + } + + pub fn has_passthrough(&self) -> bool { + self.passthrough.is_some() + } + + // Param is passed by value, moved + pub fn set_passthrough(&mut self, v: PassthroughEnum) { + self.passthrough = ::std::option::Option::Some(v); + } +} + +impl ::protobuf::Message for Show { + fn is_initialized(&self) -> bool { + for v in &self.episode { + if !v.is_initialized() { + return false; + } + }; + for v in &self.covers { + if !v.is_initialized() { + return false; + } + }; + for v in &self.restriction { + if !v.is_initialized() { + return false; + } + }; + for v in &self.categories { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.gid)?; + }, + 2 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.name)?; + }, + 70 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.episode)?; + }, + 64 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.description)?; + }, + 66 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.publisher)?; + }, + 67 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.language)?; + }, + 68 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.explicit = ::std::option::Option::Some(tmp); + }, + 69 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.covers)?; + }, + 72 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.restriction)?; + }, + 74 => { + ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.media_type, 74, &mut self.unknown_fields)? + }, + 75 => { + ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.consumption_order, 75, &mut self.unknown_fields)? + }, + 76 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.interpret_restriction_using_geoip = ::std::option::Option::Some(tmp); + }, + 79 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.country_of_origin)?; + }, + 80 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.categories)?; + }, + 81 => { + ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.passthrough, 81, &mut self.unknown_fields)? + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.gid.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + if let Some(ref v) = self.name.as_ref() { + my_size += ::protobuf::rt::string_size(2, &v); + } + for value in &self.episode { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if let Some(ref v) = self.description.as_ref() { + my_size += ::protobuf::rt::string_size(64, &v); + } + if let Some(ref v) = self.publisher.as_ref() { + my_size += ::protobuf::rt::string_size(66, &v); + } + if let Some(ref v) = self.language.as_ref() { + my_size += ::protobuf::rt::string_size(67, &v); + } + if let Some(v) = self.explicit { + my_size += 3; + } + if let Some(ref v) = self.covers.as_ref() { + let len = v.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + for value in &self.restriction { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if let Some(v) = self.media_type { + my_size += ::protobuf::rt::enum_size(74, v); + } + if let Some(v) = self.consumption_order { + my_size += ::protobuf::rt::enum_size(75, v); + } + if let Some(v) = self.interpret_restriction_using_geoip { + my_size += 3; + } + if let Some(ref v) = self.country_of_origin.as_ref() { + my_size += ::protobuf::rt::string_size(79, &v); + } + for value in &self.categories { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if let Some(v) = self.passthrough { + my_size += ::protobuf::rt::enum_size(81, v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.gid.as_ref() { + os.write_bytes(1, &v)?; + } + if let Some(ref v) = self.name.as_ref() { + os.write_string(2, &v)?; + } + for v in &self.episode { + os.write_tag(70, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if let Some(ref v) = self.description.as_ref() { + os.write_string(64, &v)?; + } + if let Some(ref v) = self.publisher.as_ref() { + os.write_string(66, &v)?; + } + if let Some(ref v) = self.language.as_ref() { + os.write_string(67, &v)?; + } + if let Some(v) = self.explicit { + os.write_bool(68, v)?; + } + if let Some(ref v) = self.covers.as_ref() { + os.write_tag(69, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + for v in &self.restriction { + os.write_tag(72, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if let Some(v) = self.media_type { + os.write_enum(74, v.value())?; + } + if let Some(v) = self.consumption_order { + os.write_enum(75, v.value())?; + } + if let Some(v) = self.interpret_restriction_using_geoip { + os.write_bool(76, v)?; + } + if let Some(ref v) = self.country_of_origin.as_ref() { + os.write_string(79, &v)?; + } + for v in &self.categories { + os.write_tag(80, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if let Some(v) = self.passthrough { + os.write_enum(81, v.value())?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Show { + Show::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, + }; + unsafe { + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "gid", + |m: &Show| { &m.gid }, + |m: &mut Show| { &mut m.gid }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &Show| { &m.name }, + |m: &mut Show| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "episode", + |m: &Show| { &m.episode }, + |m: &mut Show| { &mut m.episode }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "description", + |m: &Show| { &m.description }, + |m: &mut Show| { &mut m.description }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "publisher", + |m: &Show| { &m.publisher }, + |m: &mut Show| { &mut m.publisher }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "language", + |m: &Show| { &m.language }, + |m: &mut Show| { &mut m.language }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "explicit", + |m: &Show| { &m.explicit }, + |m: &mut Show| { &mut m.explicit }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "covers", + |m: &Show| { &m.covers }, + |m: &mut Show| { &mut m.covers }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "restriction", + |m: &Show| { &m.restriction }, + |m: &mut Show| { &mut m.restriction }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "media_type", + |m: &Show| { &m.media_type }, + |m: &mut Show| { &mut m.media_type }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "consumption_order", + |m: &Show| { &m.consumption_order }, + |m: &mut Show| { &mut m.consumption_order }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "interpret_restriction_using_geoip", + |m: &Show| { &m.interpret_restriction_using_geoip }, + |m: &mut Show| { &mut m.interpret_restriction_using_geoip }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "country_of_origin", + |m: &Show| { &m.country_of_origin }, + |m: &mut Show| { &mut m.country_of_origin }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "categories", + |m: &Show| { &m.categories }, + |m: &mut Show| { &mut m.categories }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "passthrough", + |m: &Show| { &m.passthrough }, + |m: &mut Show| { &mut m.passthrough }, + )); + ::protobuf::reflect::MessageDescriptor::new::( + "Show", + fields, + file_descriptor_proto() + ) + }) + } + } + + fn default_instance() -> &'static Show { + static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const Show, + }; + unsafe { + instance.get(Show::new) + } + } +} + +impl ::protobuf::Clear for Show { + fn clear(&mut self) { + self.gid.clear(); + self.name.clear(); + self.episode.clear(); + self.description.clear(); + self.publisher.clear(); + self.language.clear(); + self.explicit = ::std::option::Option::None; + self.covers.clear(); + self.restriction.clear(); + self.media_type = ::std::option::Option::None; + self.consumption_order = ::std::option::Option::None; + self.interpret_restriction_using_geoip = ::std::option::Option::None; + self.country_of_origin.clear(); + self.categories.clear(); + self.passthrough = ::std::option::Option::None; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Show { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Show { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Episode { + // message fields + gid: ::protobuf::SingularField<::std::vec::Vec>, + name: ::protobuf::SingularField<::std::string::String>, + duration: ::std::option::Option, + popularity: ::std::option::Option, + file: ::protobuf::RepeatedField, + description: ::protobuf::SingularField<::std::string::String>, + publish_time: ::protobuf::SingularPtrField, + covers: ::protobuf::SingularPtrField, + language: ::protobuf::SingularField<::std::string::String>, + explicit: ::std::option::Option, + show: ::protobuf::SingularPtrField, + preview: ::protobuf::RepeatedField, + restriction: ::protobuf::RepeatedField, + suppress_monetization: ::std::option::Option, + allow_background_playback: ::std::option::Option, + interpret_restriction_using_geoip: ::std::option::Option, + external_url: ::protobuf::SingularField<::std::string::String>, + original_audio: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Episode { + fn default() -> &'a Episode { + ::default_instance() + } +} + +impl Episode { + pub fn new() -> Episode { + ::std::default::Default::default() + } + + // optional bytes gid = 1; + + + pub fn get_gid(&self) -> &[u8] { + match self.gid.as_ref() { + Some(v) => &v, + None => &[], + } + } + pub fn clear_gid(&mut self) { + self.gid.clear(); + } + + pub fn has_gid(&self) -> bool { + self.gid.is_some() + } + + // Param is passed by value, moved + pub fn set_gid(&mut self, v: ::std::vec::Vec) { + self.gid = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_gid(&mut self) -> &mut ::std::vec::Vec { + if self.gid.is_none() { + self.gid.set_default(); + } + self.gid.as_mut().unwrap() + } + + // Take field + pub fn take_gid(&mut self) -> ::std::vec::Vec { + self.gid.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // optional string name = 2; + + + pub fn get_name(&self) -> &str { + match self.name.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + pub fn has_name(&self) -> bool { + self.name.is_some() + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + if self.name.is_none() { + self.name.set_default(); + } + self.name.as_mut().unwrap() + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + self.name.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // optional sint32 duration = 7; + + + pub fn get_duration(&self) -> i32 { + self.duration.unwrap_or(0) + } + pub fn clear_duration(&mut self) { + self.duration = ::std::option::Option::None; + } + + pub fn has_duration(&self) -> bool { + self.duration.is_some() + } + + // Param is passed by value, moved + pub fn set_duration(&mut self, v: i32) { + self.duration = ::std::option::Option::Some(v); + } + + // optional sint32 popularity = 8; + + + pub fn get_popularity(&self) -> i32 { + self.popularity.unwrap_or(0) + } + pub fn clear_popularity(&mut self) { + self.popularity = ::std::option::Option::None; + } + + pub fn has_popularity(&self) -> bool { + self.popularity.is_some() + } + + // Param is passed by value, moved + pub fn set_popularity(&mut self, v: i32) { + self.popularity = ::std::option::Option::Some(v); + } + + // repeated .AudioFile file = 12; + + + pub fn get_file(&self) -> &[AudioFile] { + &self.file + } + pub fn clear_file(&mut self) { + self.file.clear(); + } + + // Param is passed by value, moved + pub fn set_file(&mut self, v: ::protobuf::RepeatedField) { + self.file = v; + } + + // Mutable pointer to the field. + pub fn mut_file(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.file + } + + // Take field + pub fn take_file(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.file, ::protobuf::RepeatedField::new()) + } + + // optional string description = 64; + + + pub fn get_description(&self) -> &str { + match self.description.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_description(&mut self) { + self.description.clear(); + } + + pub fn has_description(&self) -> bool { + self.description.is_some() + } + + // Param is passed by value, moved + pub fn set_description(&mut self, v: ::std::string::String) { + self.description = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_description(&mut self) -> &mut ::std::string::String { + if self.description.is_none() { + self.description.set_default(); + } + self.description.as_mut().unwrap() + } + + // Take field + pub fn take_description(&mut self) -> ::std::string::String { + self.description.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // optional .Date publish_time = 66; + + + pub fn get_publish_time(&self) -> &Date { + self.publish_time.as_ref().unwrap_or_else(|| Date::default_instance()) + } + pub fn clear_publish_time(&mut self) { + self.publish_time.clear(); + } + + pub fn has_publish_time(&self) -> bool { + self.publish_time.is_some() + } + + // Param is passed by value, moved + pub fn set_publish_time(&mut self, v: Date) { + self.publish_time = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_publish_time(&mut self) -> &mut Date { + if self.publish_time.is_none() { + self.publish_time.set_default(); + } + self.publish_time.as_mut().unwrap() + } + + // Take field + pub fn take_publish_time(&mut self) -> Date { + self.publish_time.take().unwrap_or_else(|| Date::new()) + } + + // optional .ImageGroup covers = 68; + + + pub fn get_covers(&self) -> &ImageGroup { + self.covers.as_ref().unwrap_or_else(|| ImageGroup::default_instance()) + } + pub fn clear_covers(&mut self) { + self.covers.clear(); + } + + pub fn has_covers(&self) -> bool { + self.covers.is_some() + } + + // Param is passed by value, moved + pub fn set_covers(&mut self, v: ImageGroup) { + self.covers = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_covers(&mut self) -> &mut ImageGroup { + if self.covers.is_none() { + self.covers.set_default(); + } + self.covers.as_mut().unwrap() + } + + // Take field + pub fn take_covers(&mut self) -> ImageGroup { + self.covers.take().unwrap_or_else(|| ImageGroup::new()) + } + + // optional string language = 69; + + + pub fn get_language(&self) -> &str { + match self.language.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_language(&mut self) { + self.language.clear(); + } + + pub fn has_language(&self) -> bool { + self.language.is_some() + } + + // Param is passed by value, moved + pub fn set_language(&mut self, v: ::std::string::String) { + self.language = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_language(&mut self) -> &mut ::std::string::String { + if self.language.is_none() { + self.language.set_default(); + } + self.language.as_mut().unwrap() + } + + // Take field + pub fn take_language(&mut self) -> ::std::string::String { + self.language.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // optional bool explicit = 70; + + + pub fn get_explicit(&self) -> bool { + self.explicit.unwrap_or(false) + } + pub fn clear_explicit(&mut self) { + self.explicit = ::std::option::Option::None; + } + + pub fn has_explicit(&self) -> bool { + self.explicit.is_some() + } + + // Param is passed by value, moved + pub fn set_explicit(&mut self, v: bool) { + self.explicit = ::std::option::Option::Some(v); + } + + // optional .Show show = 71; + + + pub fn get_show(&self) -> &Show { + self.show.as_ref().unwrap_or_else(|| Show::default_instance()) + } + pub fn clear_show(&mut self) { + self.show.clear(); + } + + pub fn has_show(&self) -> bool { + self.show.is_some() + } + + // Param is passed by value, moved + pub fn set_show(&mut self, v: Show) { + self.show = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_show(&mut self) -> &mut Show { + if self.show.is_none() { + self.show.set_default(); + } + self.show.as_mut().unwrap() + } + + // Take field + pub fn take_show(&mut self) -> Show { + self.show.take().unwrap_or_else(|| Show::new()) + } + + // repeated .AudioFile preview = 74; + + + pub fn get_preview(&self) -> &[AudioFile] { + &self.preview + } + pub fn clear_preview(&mut self) { + self.preview.clear(); + } + + // Param is passed by value, moved + pub fn set_preview(&mut self, v: ::protobuf::RepeatedField) { + self.preview = v; + } + + // Mutable pointer to the field. + pub fn mut_preview(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.preview + } + + // Take field + pub fn take_preview(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.preview, ::protobuf::RepeatedField::new()) + } + + // repeated .Restriction restriction = 75; + + + pub fn get_restriction(&self) -> &[Restriction] { + &self.restriction + } + pub fn clear_restriction(&mut self) { + self.restriction.clear(); + } + + // Param is passed by value, moved + pub fn set_restriction(&mut self, v: ::protobuf::RepeatedField) { + self.restriction = v; + } + + // Mutable pointer to the field. + pub fn mut_restriction(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.restriction + } + + // Take field + pub fn take_restriction(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.restriction, ::protobuf::RepeatedField::new()) + } + + // optional bool suppress_monetization = 78; + + + pub fn get_suppress_monetization(&self) -> bool { + self.suppress_monetization.unwrap_or(false) + } + pub fn clear_suppress_monetization(&mut self) { + self.suppress_monetization = ::std::option::Option::None; + } + + pub fn has_suppress_monetization(&self) -> bool { + self.suppress_monetization.is_some() + } + + // Param is passed by value, moved + pub fn set_suppress_monetization(&mut self, v: bool) { + self.suppress_monetization = ::std::option::Option::Some(v); + } + + // optional bool allow_background_playback = 79; + + + pub fn get_allow_background_playback(&self) -> bool { + self.allow_background_playback.unwrap_or(false) + } + pub fn clear_allow_background_playback(&mut self) { + self.allow_background_playback = ::std::option::Option::None; + } + + pub fn has_allow_background_playback(&self) -> bool { + self.allow_background_playback.is_some() + } + + // Param is passed by value, moved + pub fn set_allow_background_playback(&mut self, v: bool) { + self.allow_background_playback = ::std::option::Option::Some(v); + } + + // optional bool interpret_restriction_using_geoip = 81; + + + pub fn get_interpret_restriction_using_geoip(&self) -> bool { + self.interpret_restriction_using_geoip.unwrap_or(false) + } + pub fn clear_interpret_restriction_using_geoip(&mut self) { + self.interpret_restriction_using_geoip = ::std::option::Option::None; + } + + pub fn has_interpret_restriction_using_geoip(&self) -> bool { + self.interpret_restriction_using_geoip.is_some() + } + + // Param is passed by value, moved + pub fn set_interpret_restriction_using_geoip(&mut self, v: bool) { + self.interpret_restriction_using_geoip = ::std::option::Option::Some(v); + } + + // optional string external_url = 83; + + + pub fn get_external_url(&self) -> &str { + match self.external_url.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_external_url(&mut self) { + self.external_url.clear(); + } + + pub fn has_external_url(&self) -> bool { + self.external_url.is_some() + } + + // Param is passed by value, moved + pub fn set_external_url(&mut self, v: ::std::string::String) { + self.external_url = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_external_url(&mut self) -> &mut ::std::string::String { + if self.external_url.is_none() { + self.external_url.set_default(); + } + self.external_url.as_mut().unwrap() + } + + // Take field + pub fn take_external_url(&mut self) -> ::std::string::String { + self.external_url.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // optional .OriginalAudio original_audio = 84; + + + pub fn get_original_audio(&self) -> &OriginalAudio { + self.original_audio.as_ref().unwrap_or_else(|| OriginalAudio::default_instance()) + } + pub fn clear_original_audio(&mut self) { + self.original_audio.clear(); + } + + pub fn has_original_audio(&self) -> bool { + self.original_audio.is_some() + } + + // Param is passed by value, moved + pub fn set_original_audio(&mut self, v: OriginalAudio) { + self.original_audio = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_original_audio(&mut self) -> &mut OriginalAudio { + if self.original_audio.is_none() { + self.original_audio.set_default(); + } + self.original_audio.as_mut().unwrap() + } + + // Take field + pub fn take_original_audio(&mut self) -> OriginalAudio { + self.original_audio.take().unwrap_or_else(|| OriginalAudio::new()) + } +} + +impl ::protobuf::Message for Episode { + fn is_initialized(&self) -> bool { + for v in &self.file { + if !v.is_initialized() { + return false; + } + }; + for v in &self.publish_time { + if !v.is_initialized() { + return false; + } + }; + for v in &self.covers { + if !v.is_initialized() { + return false; + } + }; + for v in &self.show { + if !v.is_initialized() { + return false; + } + }; + for v in &self.preview { + if !v.is_initialized() { + return false; + } + }; + for v in &self.restriction { + if !v.is_initialized() { + return false; + } + }; + for v in &self.original_audio { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.gid)?; + }, + 2 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.name)?; + }, + 7 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.duration = ::std::option::Option::Some(tmp); + }, + 8 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.popularity = ::std::option::Option::Some(tmp); + }, + 12 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.file)?; + }, + 64 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.description)?; + }, + 66 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.publish_time)?; + }, + 68 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.covers)?; + }, + 69 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.language)?; + }, + 70 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.explicit = ::std::option::Option::Some(tmp); + }, + 71 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.show)?; + }, + 74 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.preview)?; + }, + 75 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.restriction)?; + }, + 78 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.suppress_monetization = ::std::option::Option::Some(tmp); + }, + 79 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.allow_background_playback = ::std::option::Option::Some(tmp); + }, + 81 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.interpret_restriction_using_geoip = ::std::option::Option::Some(tmp); + }, + 83 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.external_url)?; + }, + 84 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.original_audio)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.gid.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + if let Some(ref v) = self.name.as_ref() { + my_size += ::protobuf::rt::string_size(2, &v); + } + if let Some(v) = self.duration { + my_size += ::protobuf::rt::value_varint_zigzag_size(7, v); + } + if let Some(v) = self.popularity { + my_size += ::protobuf::rt::value_varint_zigzag_size(8, v); + } + for value in &self.file { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if let Some(ref v) = self.description.as_ref() { + my_size += ::protobuf::rt::string_size(64, &v); + } + if let Some(ref v) = self.publish_time.as_ref() { + let len = v.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.covers.as_ref() { + let len = v.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + if let Some(ref v) = self.language.as_ref() { + my_size += ::protobuf::rt::string_size(69, &v); + } + if let Some(v) = self.explicit { + my_size += 3; + } + if let Some(ref v) = self.show.as_ref() { + let len = v.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + for value in &self.preview { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.restriction { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + if let Some(v) = self.suppress_monetization { + my_size += 3; + } + if let Some(v) = self.allow_background_playback { + my_size += 3; + } + if let Some(v) = self.interpret_restriction_using_geoip { + my_size += 3; + } + if let Some(ref v) = self.external_url.as_ref() { + my_size += ::protobuf::rt::string_size(83, &v); + } + if let Some(ref v) = self.original_audio.as_ref() { + let len = v.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.gid.as_ref() { + os.write_bytes(1, &v)?; + } + if let Some(ref v) = self.name.as_ref() { + os.write_string(2, &v)?; + } + if let Some(v) = self.duration { + os.write_sint32(7, v)?; + } + if let Some(v) = self.popularity { + os.write_sint32(8, v)?; + } + for v in &self.file { + os.write_tag(12, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if let Some(ref v) = self.description.as_ref() { + os.write_string(64, &v)?; + } + if let Some(ref v) = self.publish_time.as_ref() { + os.write_tag(66, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let Some(ref v) = self.covers.as_ref() { + os.write_tag(68, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + if let Some(ref v) = self.language.as_ref() { + os.write_string(69, &v)?; + } + if let Some(v) = self.explicit { + os.write_bool(70, v)?; + } + if let Some(ref v) = self.show.as_ref() { + os.write_tag(71, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + for v in &self.preview { + os.write_tag(74, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.restriction { + os.write_tag(75, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + if let Some(v) = self.suppress_monetization { + os.write_bool(78, v)?; + } + if let Some(v) = self.allow_background_playback { + os.write_bool(79, v)?; + } + if let Some(v) = self.interpret_restriction_using_geoip { + os.write_bool(81, v)?; + } + if let Some(ref v) = self.external_url.as_ref() { + os.write_string(83, &v)?; + } + if let Some(ref v) = self.original_audio.as_ref() { + os.write_tag(84, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Episode { + Episode::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, + }; + unsafe { + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "gid", + |m: &Episode| { &m.gid }, + |m: &mut Episode| { &mut m.gid }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &Episode| { &m.name }, + |m: &mut Episode| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "duration", + |m: &Episode| { &m.duration }, + |m: &mut Episode| { &mut m.duration }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "popularity", + |m: &Episode| { &m.popularity }, + |m: &mut Episode| { &mut m.popularity }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "file", + |m: &Episode| { &m.file }, + |m: &mut Episode| { &mut m.file }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "description", + |m: &Episode| { &m.description }, + |m: &mut Episode| { &mut m.description }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "publish_time", + |m: &Episode| { &m.publish_time }, + |m: &mut Episode| { &mut m.publish_time }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "covers", + |m: &Episode| { &m.covers }, + |m: &mut Episode| { &mut m.covers }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "language", + |m: &Episode| { &m.language }, + |m: &mut Episode| { &mut m.language }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "explicit", + |m: &Episode| { &m.explicit }, + |m: &mut Episode| { &mut m.explicit }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "show", + |m: &Episode| { &m.show }, + |m: &mut Episode| { &mut m.show }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "preview", + |m: &Episode| { &m.preview }, + |m: &mut Episode| { &mut m.preview }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "restriction", + |m: &Episode| { &m.restriction }, + |m: &mut Episode| { &mut m.restriction }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "suppress_monetization", + |m: &Episode| { &m.suppress_monetization }, + |m: &mut Episode| { &mut m.suppress_monetization }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "allow_background_playback", + |m: &Episode| { &m.allow_background_playback }, + |m: &mut Episode| { &mut m.allow_background_playback }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "interpret_restriction_using_geoip", + |m: &Episode| { &m.interpret_restriction_using_geoip }, + |m: &mut Episode| { &mut m.interpret_restriction_using_geoip }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "external_url", + |m: &Episode| { &m.external_url }, + |m: &mut Episode| { &mut m.external_url }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "original_audio", + |m: &Episode| { &m.original_audio }, + |m: &mut Episode| { &mut m.original_audio }, + )); + ::protobuf::reflect::MessageDescriptor::new::( + "Episode", + fields, + file_descriptor_proto() + ) + }) + } + } + + fn default_instance() -> &'static Episode { + static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const Episode, + }; + unsafe { + instance.get(Episode::new) + } + } +} + +impl ::protobuf::Clear for Episode { + fn clear(&mut self) { + self.gid.clear(); + self.name.clear(); + self.duration = ::std::option::Option::None; + self.popularity = ::std::option::Option::None; + self.file.clear(); + self.description.clear(); + self.publish_time.clear(); + self.covers.clear(); + self.language.clear(); + self.explicit = ::std::option::Option::None; + self.show.clear(); + self.preview.clear(); + self.restriction.clear(); + self.suppress_monetization = ::std::option::Option::None; + self.allow_background_playback = ::std::option::Option::None; + self.interpret_restriction_using_geoip = ::std::option::Option::None; + self.external_url.clear(); + self.original_audio.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Episode { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Episode { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct Category { + // message fields + name: ::protobuf::SingularField<::std::string::String>, + subcategories: ::protobuf::RepeatedField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Category { + fn default() -> &'a Category { + ::default_instance() + } +} + +impl Category { + pub fn new() -> Category { + ::std::default::Default::default() + } + + // optional string name = 1; + + + pub fn get_name(&self) -> &str { + match self.name.as_ref() { + Some(v) => &v, + None => "", + } + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + pub fn has_name(&self) -> bool { + self.name.is_some() + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + if self.name.is_none() { + self.name.set_default(); + } + self.name.as_mut().unwrap() + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + self.name.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // repeated .Category subcategories = 2; + + + pub fn get_subcategories(&self) -> &[Category] { + &self.subcategories + } + pub fn clear_subcategories(&mut self) { + self.subcategories.clear(); + } + + // Param is passed by value, moved + pub fn set_subcategories(&mut self, v: ::protobuf::RepeatedField) { + self.subcategories = v; + } + + // Mutable pointer to the field. + pub fn mut_subcategories(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.subcategories + } + + // Take field + pub fn take_subcategories(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.subcategories, ::protobuf::RepeatedField::new()) + } +} + +impl ::protobuf::Message for Category { + fn is_initialized(&self) -> bool { + for v in &self.subcategories { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.name)?; + }, + 2 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.subcategories)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.name.as_ref() { + my_size += ::protobuf::rt::string_size(1, &v); + } + for value in &self.subcategories { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.name.as_ref() { + os.write_string(1, &v)?; + } + for v in &self.subcategories { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Category { + Category::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, + }; + unsafe { + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &Category| { &m.name }, + |m: &mut Category| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "subcategories", + |m: &Category| { &m.subcategories }, + |m: &mut Category| { &mut m.subcategories }, + )); + ::protobuf::reflect::MessageDescriptor::new::( + "Category", + fields, + file_descriptor_proto() + ) + }) + } + } + + fn default_instance() -> &'static Category { + static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const Category, + }; + unsafe { + instance.get(Category::new) + } + } +} + +impl ::protobuf::Clear for Category { + fn clear(&mut self) { + self.name.clear(); + self.subcategories.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Category { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Category { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct OriginalAudio { + // message fields + uuid: ::protobuf::SingularField<::std::vec::Vec>, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a OriginalAudio { + fn default() -> &'a OriginalAudio { + ::default_instance() + } +} + +impl OriginalAudio { + pub fn new() -> OriginalAudio { + ::std::default::Default::default() + } + + // optional bytes uuid = 1; + + + pub fn get_uuid(&self) -> &[u8] { + match self.uuid.as_ref() { + Some(v) => &v, + None => &[], + } + } + pub fn clear_uuid(&mut self) { + self.uuid.clear(); + } + + pub fn has_uuid(&self) -> bool { + self.uuid.is_some() + } + + // Param is passed by value, moved + pub fn set_uuid(&mut self, v: ::std::vec::Vec) { + self.uuid = ::protobuf::SingularField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_uuid(&mut self) -> &mut ::std::vec::Vec { + if self.uuid.is_none() { + self.uuid.set_default(); + } + self.uuid.as_mut().unwrap() + } + + // Take field + pub fn take_uuid(&mut self) -> ::std::vec::Vec { + self.uuid.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } +} + +impl ::protobuf::Message for OriginalAudio { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.uuid)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if let Some(ref v) = self.uuid.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + if let Some(ref v) = self.uuid.as_ref() { + os.write_bytes(1, &v)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> OriginalAudio { + OriginalAudio::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, + }; + unsafe { + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "uuid", + |m: &OriginalAudio| { &m.uuid }, + |m: &mut OriginalAudio| { &mut m.uuid }, + )); + ::protobuf::reflect::MessageDescriptor::new::( + "OriginalAudio", + fields, + file_descriptor_proto() + ) + }) + } + } + + fn default_instance() -> &'static OriginalAudio { + static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const OriginalAudio, + }; + unsafe { + instance.get(OriginalAudio::new) + } + } +} + +impl ::protobuf::Clear for OriginalAudio { + fn clear(&mut self) { + self.uuid.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for OriginalAudio { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for OriginalAudio { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum ConsumptionOrder { + SEQUENTIAL = 1, + EPISODIC = 2, + RECENT = 3, +} + +impl ::protobuf::ProtobufEnum for ConsumptionOrder { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 1 => ::std::option::Option::Some(ConsumptionOrder::SEQUENTIAL), + 2 => ::std::option::Option::Some(ConsumptionOrder::EPISODIC), + 3 => ::std::option::Option::Some(ConsumptionOrder::RECENT), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [ConsumptionOrder] = &[ + ConsumptionOrder::SEQUENTIAL, + ConsumptionOrder::EPISODIC, + ConsumptionOrder::RECENT, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, + }; + unsafe { + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new("ConsumptionOrder", file_descriptor_proto()) + }) + } + } +} + +impl ::std::marker::Copy for ConsumptionOrder { +} + +// Note, `Default` is implemented although default value is not 0 +impl ::std::default::Default for ConsumptionOrder { + fn default() -> Self { + ConsumptionOrder::SEQUENTIAL + } +} + +impl ::protobuf::reflect::ProtobufValue for ConsumptionOrder { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum MediaType { + MIXED = 0, + AUDIO = 1, + VIDEO = 2, +} + +impl ::protobuf::ProtobufEnum for MediaType { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(MediaType::MIXED), + 1 => ::std::option::Option::Some(MediaType::AUDIO), + 2 => ::std::option::Option::Some(MediaType::VIDEO), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [MediaType] = &[ + MediaType::MIXED, + MediaType::AUDIO, + MediaType::VIDEO, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, + }; + unsafe { + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new("MediaType", file_descriptor_proto()) + }) + } + } +} + +impl ::std::marker::Copy for MediaType { +} + +impl ::std::default::Default for MediaType { + fn default() -> Self { + MediaType::MIXED + } +} + +impl ::protobuf::reflect::ProtobufValue for MediaType { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum PassthroughEnum { + UNKNOWN = 0, + NONE = 1, +} + +impl ::protobuf::ProtobufEnum for PassthroughEnum { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(PassthroughEnum::UNKNOWN), + 1 => ::std::option::Option::Some(PassthroughEnum::NONE), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [PassthroughEnum] = &[ + PassthroughEnum::UNKNOWN, + PassthroughEnum::NONE, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, + }; + unsafe { + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new("PassthroughEnum", file_descriptor_proto()) + }) + } + } +} + +impl ::std::marker::Copy for PassthroughEnum { +} + +impl ::std::default::Default for PassthroughEnum { + fn default() -> Self { + PassthroughEnum::UNKNOWN + } +} + +impl ::protobuf::reflect::ProtobufValue for PassthroughEnum { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) + } +} + static file_descriptor_proto_data: &'static [u8] = b"\ \n\x0emetadata.proto\x12\0\"9\n\tTopTracks\x12\x11\n\x07country\x18\x01\ \x20\x01(\tB\0\x12\x17\n\x05track\x18\x02\x20\x03(\x0b2\x06.TrackB\0:\0\ @@ -6293,15 +9016,50 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\x01\x20\x03(\x0b2\x0c.RestrictionB\0\x12\x16\n\x05start\x18\x02\x20\ \x01(\x0b2\x05.DateB\0\x12\x14\n\x03end\x18\x03\x20\x01(\x0b2\x05.DateB\ \0:\0\"+\n\nExternalId\x12\r\n\x03typ\x18\x01\x20\x01(\tB\0\x12\x0c\n\ - \x02id\x18\x02\x20\x01(\tB\0:\0\"\x9b\x02\n\tAudioFile\x12\x11\n\x07file\ + \x02id\x18\x02\x20\x01(\tB\0:\0\"\xa2\x02\n\tAudioFile\x12\x11\n\x07file\ _id\x18\x01\x20\x01(\x0cB\0\x12#\n\x06format\x18\x02\x20\x01(\x0e2\x11.A\ - udioFile.FormatB\0\"\xd3\x01\n\x06Format\x12\x11\n\rOGG_VORBIS_96\x10\0\ + udioFile.FormatB\0\"\xda\x01\n\x06Format\x12\x11\n\rOGG_VORBIS_96\x10\0\ \x12\x12\n\x0eOGG_VORBIS_160\x10\x01\x12\x12\n\x0eOGG_VORBIS_320\x10\x02\ \x12\x0b\n\x07MP3_256\x10\x03\x12\x0b\n\x07MP3_320\x10\x04\x12\x0b\n\x07\ MP3_160\x10\x05\x12\n\n\x06MP3_96\x10\x06\x12\x0f\n\x0bMP3_160_ENC\x10\ - \x07\x12\n\n\x06OTHER2\x10\x08\x12\n\n\x06OTHER3\x10\t\x12\x0b\n\x07AAC_\ - 160\x10\n\x12\x0b\n\x07AAC_320\x10\x0b\x12\n\n\x06OTHER4\x10\x0c\x12\n\n\ - \x06OTHER5\x10\r\x1a\0:\0B\0b\x06proto2\ + \x07\x12\x10\n\x0cMP4_128_DUAL\x10\x08\x12\n\n\x06OTHER3\x10\t\x12\x0b\n\ + \x07AAC_160\x10\n\x12\x0b\n\x07AAC_320\x10\x0b\x12\x0b\n\x07MP4_128\x10\ + \x0c\x12\n\n\x06OTHER5\x10\r\x1a\0:\0\"a\n\x0bPublishTime\x12\x0e\n\x04y\ + ear\x18\x01\x20\x01(\x11B\0\x12\x0f\n\x05month\x18\x02\x20\x01(\x11B\0\ + \x12\r\n\x03day\x18\x03\x20\x01(\x11B\0\x12\x10\n\x06minute\x18\x05\x20\ + \x01(\x11B\0\x12\x0e\n\x04hour\x18\x04\x20\x01(\x11B\0:\0\"\xc2\x03\n\ + \x04Show\x12\r\n\x03gid\x18\x01\x20\x01(\x0cB\0\x12\x0e\n\x04name\x18\ + \x02\x20\x01(\tB\0\x12\x1b\n\x07episode\x18F\x20\x03(\x0b2\x08.EpisodeB\ + \0\x12\x15\n\x0bdescription\x18@\x20\x01(\tB\0\x12\x13\n\tpublisher\x18B\ + \x20\x01(\tB\0\x12\x12\n\x08language\x18C\x20\x01(\tB\0\x12\x12\n\x08exp\ + licit\x18D\x20\x01(\x08B\0\x12\x1d\n\x06covers\x18E\x20\x01(\x0b2\x0b.Im\ + ageGroupB\0\x12#\n\x0brestriction\x18H\x20\x03(\x0b2\x0c.RestrictionB\0\ + \x12\x20\n\nmedia_type\x18J\x20\x01(\x0e2\n.MediaTypeB\0\x12.\n\x11consu\ + mption_order\x18K\x20\x01(\x0e2\x11.ConsumptionOrderB\0\x12+\n!interpret\ + _restriction_using_geoip\x18L\x20\x01(\x08B\0\x12\x1b\n\x11country_of_or\ + igin\x18O\x20\x01(\tB\0\x12\x1f\n\ncategories\x18P\x20\x03(\x0b2\t.Categ\ + oryB\0\x12'\n\x0bpassthrough\x18Q\x20\x01(\x0e2\x10.PassthroughEnumB\0:\ + \0\"\xfd\x03\n\x07Episode\x12\r\n\x03gid\x18\x01\x20\x01(\x0cB\0\x12\x0e\ + \n\x04name\x18\x02\x20\x01(\tB\0\x12\x12\n\x08duration\x18\x07\x20\x01(\ + \x11B\0\x12\x14\n\npopularity\x18\x08\x20\x01(\x11B\0\x12\x1a\n\x04file\ + \x18\x0c\x20\x03(\x0b2\n.AudioFileB\0\x12\x15\n\x0bdescription\x18@\x20\ + \x01(\tB\0\x12\x1d\n\x0cpublish_time\x18B\x20\x01(\x0b2\x05.DateB\0\x12\ + \x1d\n\x06covers\x18D\x20\x01(\x0b2\x0b.ImageGroupB\0\x12\x12\n\x08langu\ + age\x18E\x20\x01(\tB\0\x12\x12\n\x08explicit\x18F\x20\x01(\x08B\0\x12\ + \x15\n\x04show\x18G\x20\x01(\x0b2\x05.ShowB\0\x12\x1d\n\x07preview\x18J\ + \x20\x03(\x0b2\n.AudioFileB\0\x12#\n\x0brestriction\x18K\x20\x03(\x0b2\ + \x0c.RestrictionB\0\x12\x1f\n\x15suppress_monetization\x18N\x20\x01(\x08\ + B\0\x12#\n\x19allow_background_playback\x18O\x20\x01(\x08B\0\x12+\n!inte\ + rpret_restriction_using_geoip\x18Q\x20\x01(\x08B\0\x12\x16\n\x0cexternal\ + _url\x18S\x20\x01(\tB\0\x12(\n\x0eoriginal_audio\x18T\x20\x01(\x0b2\x0e.\ + OriginalAudioB\0:\0\"@\n\x08Category\x12\x0e\n\x04name\x18\x01\x20\x01(\ + \tB\0\x12\"\n\rsubcategories\x18\x02\x20\x03(\x0b2\t.CategoryB\0:\0\"!\n\ + \rOriginalAudio\x12\x0e\n\x04uuid\x18\x01\x20\x01(\x0cB\0:\0*>\n\x10Cons\ + umptionOrder\x12\x0e\n\nSEQUENTIAL\x10\x01\x12\x0c\n\x08EPISODIC\x10\x02\ + \x12\n\n\x06RECENT\x10\x03\x1a\0*.\n\tMediaType\x12\t\n\x05MIXED\x10\0\ + \x12\t\n\x05AUDIO\x10\x01\x12\t\n\x05VIDEO\x10\x02\x1a\0**\n\x0fPassthro\ + ughEnum\x12\x0b\n\x07UNKNOWN\x10\0\x12\x08\n\x04NONE\x10\x01\x1a\0B\0b\ + \x06proto2\ "; static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { From 8eb51e9b55d6051ced1275ac15a5578b307a3eb0 Mon Sep 17 00:00:00 2001 From: ashthespy Date: Tue, 8 Oct 2019 00:27:26 +0200 Subject: [PATCH 3/8] Streamline and refactor Podcast support, Add publisher to `Show` Add `ALLOWED` to `PassthroughEnum` --- core/src/spotify_id.rs | 8 +-- metadata/src/lib.rs | 71 +++++++++++++++++- playback/src/player.rs | 132 ++++++++++++++-------------------- protocol/files.rs | 2 +- protocol/proto/metadata.proto | 1 + protocol/src/metadata.rs | 9 ++- 6 files changed, 135 insertions(+), 88 deletions(-) diff --git a/core/src/spotify_id.rs b/core/src/spotify_id.rs index 01c4ddd4..c8f01674 100644 --- a/core/src/spotify_id.rs +++ b/core/src/spotify_id.rs @@ -2,7 +2,7 @@ use std; use std::fmt; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum SpotifyTrackType { +pub enum SpotifyAudioType { Track, Podcast, } @@ -10,7 +10,7 @@ pub enum SpotifyTrackType { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct SpotifyId { pub id: u128, - pub track_type: SpotifyTrackType, + pub audio_type: SpotifyAudioType, } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -23,7 +23,7 @@ impl SpotifyId { fn as_track(n: u128) -> SpotifyId { SpotifyId { id: n.to_owned(), - track_type: SpotifyTrackType::Track, + audio_type: SpotifyAudioType::Track, } } @@ -73,7 +73,7 @@ impl SpotifyId { let parts = uri.split(":").collect::>(); if uri.contains(":show:") || uri.contains(":episode:") { let mut spotify_id = SpotifyId::from_base62(parts[2]).unwrap(); - spotify_id.track_type = SpotifyTrackType::Podcast; + let _ = std::mem::replace(&mut spotify_id.audio_type, SpotifyAudioType::Podcast); Ok(spotify_id) } else { SpotifyId::from_base62(parts[2]) diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 6aa6a5bd..75a42e2f 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -13,7 +13,7 @@ use linear_map::LinearMap; use librespot_core::mercury::MercuryError; use librespot_core::session::Session; -use librespot_core::spotify_id::{FileId, SpotifyId}; +use librespot_core::spotify_id::{FileId, SpotifyAudioType, SpotifyId}; pub use protocol::metadata::AudioFile_Format as FileFormat; @@ -52,13 +52,78 @@ where && (!has_allowed || countrylist_contains(allowed.as_str(), country)) } +// A wrapper with fields the player needs +#[derive(Debug, Clone)] +pub struct AudioItem { + pub id: SpotifyId, + pub uri: String, + pub files: LinearMap, + pub name: String, + pub available: bool, + pub alternatives: Option>, +} + +impl AudioItem { + pub fn get_audio_item( + session: &Session, + id: SpotifyId, + ) -> Box> { + match id.audio_type { + SpotifyAudioType::Track => Track::get_audio_item(session, id), + SpotifyAudioType::Podcast => Episode::get_audio_item(session, id), + } + } +} + +trait AudioFiles { + fn get_audio_item( + session: &Session, + id: SpotifyId, + ) -> Box>; +} + +impl AudioFiles for Track { + fn get_audio_item( + session: &Session, + id: SpotifyId, + ) -> Box> { + Box::new(Self::get(session, id).and_then(move |item| { + Ok(AudioItem { + id: id, + uri: format!("spotify:track:{}", id.to_base62()), + files: item.files, + name: item.name, + available: item.available, + alternatives: Some(item.alternatives), + }) + })) + } +} + +impl AudioFiles for Episode { + fn get_audio_item( + session: &Session, + id: SpotifyId, + ) -> Box> { + Box::new(Self::get(session, id).and_then(move |item| { + Ok(AudioItem { + id: id, + uri: format!("spotify:episode:{}", id.to_base62()), + files: item.files, + name: item.name, + available: item.available, + alternatives: None, + }) + })) + } +} pub trait Metadata: Send + Sized + 'static { type Message: protobuf::Message; fn base_url() -> &'static str; fn parse(msg: &Self::Message, session: &Session) -> Self; - fn get(session: &Session, id: SpotifyId) -> Box> { + fn get(session: &Session, id: SpotifyId) -> Box> { let uri = format!("{}/{}", Self::base_url(), id.to_base16()); let request = session.mercury().get(uri); @@ -111,6 +176,7 @@ pub struct Episode { pub struct Show { pub id: SpotifyId, pub name: String, + pub publisher: String, pub episodes: Vec, pub covers: Vec, } @@ -323,6 +389,7 @@ impl Metadata for Show { Show { id: SpotifyId::from_raw(msg.get_gid()).unwrap(), name: msg.get_name().to_owned(), + publisher: msg.get_publisher().to_owned(), episodes: episodes, covers: covers, } diff --git a/playback/src/player.rs b/playback/src/player.rs index 3b48a594..95eb549d 100644 --- a/playback/src/player.rs +++ b/playback/src/player.rs @@ -12,12 +12,12 @@ use std::time::Duration; use config::{Bitrate, PlayerConfig}; use librespot_core::session::Session; -use librespot_core::spotify_id::{FileId, SpotifyId, SpotifyTrackType}; +use librespot_core::spotify_id::SpotifyId; use audio::{AudioDecrypt, AudioFile}; use audio::{VorbisDecoder, VorbisPacket}; use audio_backend::Sink; -use metadata::{Episode, FileFormat, Metadata, Track}; +use metadata::{AudioItem, FileFormat}; use mixer::AudioFilter; pub struct Player { @@ -512,87 +512,65 @@ impl PlayerInternal { let _ = self.event_sender.unbounded_send(event.clone()); } - fn find_available_alternative<'a>(&self, track: &'a Track) -> Option> { - if track.available { - Some(Cow::Borrowed(track)) + fn find_available_alternative<'a>(&self, audio: &'a AudioItem) -> Option> { + if audio.available { + Some(Cow::Borrowed(audio)) } else { - let alternatives = track - .alternatives - .iter() - .map(|alt_id| Track::get(&self.session, *alt_id)); - let alternatives = future::join_all(alternatives).wait().unwrap(); - - alternatives.into_iter().find(|alt| alt.available).map(Cow::Owned) + if let Some(alternatives) = &audio.alternatives { + let alternatives = alternatives + .iter() + .map(|alt_id| AudioItem::get_audio_item(&self.session, *alt_id)); + let alternatives = future::join_all(alternatives).wait().unwrap(); + alternatives.into_iter().find(|alt| alt.available).map(Cow::Owned) + } else { + None + } } } - fn get_file_id(&self, spotify_id: SpotifyId) -> Option { - let file_id = match spotify_id.track_type { - SpotifyTrackType::Track => { - let track = Track::get(&self.session, spotify_id).wait().unwrap(); + fn load_track(&self, spotify_id: SpotifyId, position: i64) -> Option<(Decoder, f32)> { + let audio = AudioItem::get_audio_item(&self.session, spotify_id) + .wait() + .unwrap(); + info!("Loading <{}> with Spotify URI <{}>", audio.name, audio.uri); - info!( - "Loading track \"{}\" with Spotify URI \"spotify:track:{}\"", - track.name, - spotify_id.to_base62() - ); - - let track = match self.find_available_alternative(&track) { - Some(track) => track, - None => { - warn!("Track \"{}\" is not available", track.name); - return None; - } - }; - - let format = match self.config.bitrate { - Bitrate::Bitrate96 => FileFormat::OGG_VORBIS_96, - Bitrate::Bitrate160 => FileFormat::OGG_VORBIS_160, - Bitrate::Bitrate320 => FileFormat::OGG_VORBIS_320, - }; - match track.files.get(&format) { - Some(&file_id) => file_id, - None => { - warn!("Track \"{}\" is not available in format {:?}", track.name, format); - return None; - } - } - } - // This should be refactored! - SpotifyTrackType::Podcast => { - let episode = Episode::get(&self.session, spotify_id).wait().unwrap(); - info!("Episode {:?}", episode); - - info!( - "Loading episode \"{}\" with Spotify URI \"spotify:episode:{}\"", - episode.name, - spotify_id.to_base62() - ); - - // Podcasts seem to have only 96 OGG_VORBIS support, other filetypes indicate - // AAC_24, MP4_128, MP4_128_DUAL, MP3_96 among others - let format = match self.config.bitrate { - _ => FileFormat::OGG_VORBIS_96, - }; - - match episode.files.get(&format) { - Some(&file_id) => file_id, - None => { - warn!( - "Episode \"{}\" is not available in format {:?}", - episode.name, format - ); - return None; - } - } + let audio = match self.find_available_alternative(&audio) { + Some(audio) => audio, + None => { + warn!("<{}> is not available", audio.uri); + return None; } }; - return Some(file_id); - } + // (Most) podcasts seem to support only 96 bit Vorbis, so fall back to it + let formats = match self.config.bitrate { + Bitrate::Bitrate96 => [ + FileFormat::OGG_VORBIS_96, + FileFormat::OGG_VORBIS_160, + FileFormat::OGG_VORBIS_320, + ], + Bitrate::Bitrate160 => [ + FileFormat::OGG_VORBIS_160, + FileFormat::OGG_VORBIS_96, + FileFormat::OGG_VORBIS_320, + ], + Bitrate::Bitrate320 => [ + FileFormat::OGG_VORBIS_320, + FileFormat::OGG_VORBIS_160, + FileFormat::OGG_VORBIS_96, + ], + }; + let format = formats + .iter() + .find(|format| audio.files.contains_key(format)) + .unwrap(); - fn load_track(&self, spotify_id: SpotifyId, position: i64) -> Option<(Decoder, f32)> { - let file_id = self.get_file_id(spotify_id).unwrap(); - info!("{:?} -> {:?}", spotify_id, file_id); + let file_id = match audio.files.get(&format) { + Some(&file_id) => file_id, + None => { + warn!("<{}> in not available in format {:?}", audio.name, format); + return None; + } + }; let key = self.session.audio_key().request(spotify_id, file_id); let encrypted_file = AudioFile::open(&self.session, file_id); @@ -619,9 +597,7 @@ impl PlayerInternal { Err(err) => error!("Vorbis error: {:?}", err), } } - - // info!("Track \"{}\" loaded", track.name); - + info!("<{}> loaded", audio.name); Some((decoder, normalisation_factor)) } } diff --git a/protocol/files.rs b/protocol/files.rs index f4ddd9ad..7086bd3d 100644 --- a/protocol/files.rs +++ b/protocol/files.rs @@ -3,7 +3,7 @@ pub const FILES: &'static [(&'static str, u32)] = &[ ("proto/authentication.proto", 2098196376), ("proto/keyexchange.proto", 451735664), ("proto/mercury.proto", 709993906), - ("proto/metadata.proto", 1409162985), + ("proto/metadata.proto", 334477813), ("proto/pubsub.proto", 2686584829), ("proto/spirc.proto", 1587493382), ]; diff --git a/protocol/proto/metadata.proto b/protocol/proto/metadata.proto index c3730ca7..c6c86ab6 100644 --- a/protocol/proto/metadata.proto +++ b/protocol/proto/metadata.proto @@ -207,6 +207,7 @@ enum MediaType { enum PassthroughEnum { UNKNOWN = 0; NONE = 1; + ALLOWED = 2; } message Episode { diff --git a/protocol/src/metadata.rs b/protocol/src/metadata.rs index 1a1a7f00..7d38e02d 100644 --- a/protocol/src/metadata.rs +++ b/protocol/src/metadata.rs @@ -8896,6 +8896,7 @@ impl ::protobuf::reflect::ProtobufValue for MediaType { pub enum PassthroughEnum { UNKNOWN = 0, NONE = 1, + ALLOWED = 2, } impl ::protobuf::ProtobufEnum for PassthroughEnum { @@ -8907,6 +8908,7 @@ impl ::protobuf::ProtobufEnum for PassthroughEnum { match value { 0 => ::std::option::Option::Some(PassthroughEnum::UNKNOWN), 1 => ::std::option::Option::Some(PassthroughEnum::NONE), + 2 => ::std::option::Option::Some(PassthroughEnum::ALLOWED), _ => ::std::option::Option::None } } @@ -8915,6 +8917,7 @@ impl ::protobuf::ProtobufEnum for PassthroughEnum { static values: &'static [PassthroughEnum] = &[ PassthroughEnum::UNKNOWN, PassthroughEnum::NONE, + PassthroughEnum::ALLOWED, ]; values } @@ -9057,9 +9060,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \rOriginalAudio\x12\x0e\n\x04uuid\x18\x01\x20\x01(\x0cB\0:\0*>\n\x10Cons\ umptionOrder\x12\x0e\n\nSEQUENTIAL\x10\x01\x12\x0c\n\x08EPISODIC\x10\x02\ \x12\n\n\x06RECENT\x10\x03\x1a\0*.\n\tMediaType\x12\t\n\x05MIXED\x10\0\ - \x12\t\n\x05AUDIO\x10\x01\x12\t\n\x05VIDEO\x10\x02\x1a\0**\n\x0fPassthro\ - ughEnum\x12\x0b\n\x07UNKNOWN\x10\0\x12\x08\n\x04NONE\x10\x01\x1a\0B\0b\ - \x06proto2\ + \x12\t\n\x05AUDIO\x10\x01\x12\t\n\x05VIDEO\x10\x02\x1a\0*7\n\x0fPassthro\ + ughEnum\x12\x0b\n\x07UNKNOWN\x10\0\x12\x08\n\x04NONE\x10\x01\x12\x0b\n\ + \x07ALLOWED\x10\x02\x1a\0B\0b\x06proto2\ "; static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { From 6786c093ad31a69e66ab6782287d4b4b7242bc9d Mon Sep 17 00:00:00 2001 From: ashthespy Date: Tue, 8 Oct 2019 19:20:18 +0200 Subject: [PATCH 4/8] Update `metadata.proto` --- protocol/files.rs | 9 - protocol/proto/metadata.proto | 91 +- protocol/src/metadata.rs | 1876 +++++++++++++++++++++++---------- 3 files changed, 1384 insertions(+), 592 deletions(-) delete mode 100644 protocol/files.rs diff --git a/protocol/files.rs b/protocol/files.rs deleted file mode 100644 index 7086bd3d..00000000 --- a/protocol/files.rs +++ /dev/null @@ -1,9 +0,0 @@ -// Autogenerated by build.rs -pub const FILES: &'static [(&'static str, u32)] = &[ - ("proto/authentication.proto", 2098196376), - ("proto/keyexchange.proto", 451735664), - ("proto/mercury.proto", 709993906), - ("proto/metadata.proto", 334477813), - ("proto/pubsub.proto", 2686584829), - ("proto/spirc.proto", 1587493382), -]; diff --git a/protocol/proto/metadata.proto b/protocol/proto/metadata.proto index c6c86ab6..3812f94e 100644 --- a/protocol/proto/metadata.proto +++ b/protocol/proto/metadata.proto @@ -39,6 +39,8 @@ message Date { optional sint32 year = 0x1; optional sint32 month = 0x2; optional sint32 day = 0x3; + optional sint32 hour = 0x4; + optional sint32 minute = 0x5; } message Album { @@ -124,15 +126,29 @@ message Copyright { } message Restriction { - optional string countries_allowed = 0x2; - optional string countries_forbidden = 0x3; - optional Type typ = 0x4; + enum Catalogue { + AD = 0; + SUBSCRIPTION = 1; + CATALOGUE_ALL = 2; + SHUFFLE = 3; + COMMERCIAL = 4; + } enum Type { STREAMING = 0x0; } + repeated Catalogue catalogue = 0x1; + optional string countries_allowed = 0x2; + optional string countries_forbidden = 0x3; + optional Type typ = 0x4; + repeated string catalogue_str = 0x5; } +message Availability { + repeated string catalogue_str = 0x1; + optional Date start = 0x2; +} + message SalePeriod { repeated Restriction restriction = 0x1; optional Date start = 0x2; @@ -156,6 +172,9 @@ message AudioFile { MP3_160 = 0x5; MP3_96 = 0x6; MP3_160_ENC = 0x7; + // v4 + // AAC_24 = 0x8; + // AAC_48 = 0x9; MP4_128_DUAL = 0x8; OTHER3 = 0x9; AAC_160 = 0xa; @@ -165,70 +184,74 @@ message AudioFile { } } -// Podcast Protos -message PublishTime { - optional sint32 year = 0x1; - optional sint32 month = 0x2; - optional sint32 day = 0x3; - // These seem to be differently encoded - optional sint32 minute = 0x5; - optional sint32 hour = 0x4; +message VideoFile { + optional bytes file_id = 1; } +// Podcast Protos message Show { + enum MediaType { + MIXED = 0; + AUDIO = 1; + VIDEO = 2; + } + enum ConsumptionOrder { + SEQUENTIAL = 1; + EPISODIC = 2; + RECENT = 3; + } + enum PassthroughEnum { + UNKNOWN = 0; + NONE = 1; + ALLOWED = 2; + } optional bytes gid = 0x1; optional string name = 0x2; - repeated Episode episode = 0x46; - // Educated guesses optional string description = 0x40; + optional sint32 deprecated_popularity = 0x41; optional string publisher = 0x42; optional string language = 0x43; optional bool explicit = 0x44; optional ImageGroup covers = 0x45; + repeated Episode episode = 0x46; + repeated Copyright copyright = 0x47; repeated Restriction restriction = 0x48; + repeated string keyword = 0x49; optional MediaType media_type = 0x4A; optional ConsumptionOrder consumption_order = 0x4B; optional bool interpret_restriction_using_geoip = 0x4C; + repeated Availability availability = 0x4E; optional string country_of_origin = 0x4F; repeated Category categories = 0x50; optional PassthroughEnum passthrough = 0x51; } -enum ConsumptionOrder { - SEQUENTIAL = 1; - EPISODIC = 2; - RECENT = 3; - } -enum MediaType { - MIXED = 0; - AUDIO = 1; - VIDEO = 2; -} -enum PassthroughEnum { - UNKNOWN = 0; - NONE = 1; - ALLOWED = 2; -} - message Episode { optional bytes gid = 0x1; optional string name = 0x2; optional sint32 duration = 0x7; optional sint32 popularity = 0x8; repeated AudioFile file = 0xc; - // Educated guesses optional string description = 0x40; + optional sint32 number = 0x41; optional Date publish_time = 0x42; + optional sint32 deprecated_popularity = 0x43; optional ImageGroup covers = 0x44; optional string language = 0x45; optional bool explicit = 0x46; optional Show show = 0x47; - repeated AudioFile preview = 0x4A; + repeated VideoFile video = 0x48; + repeated VideoFile video_preview = 0x49; + repeated AudioFile audio_preview = 0x4A; repeated Restriction restriction = 0x4B; - // Order of these flags might be wrong! + optional ImageGroup freeze_frame = 0x4C; + repeated string keyword = 0x4D; + // Order of these two flags might be wrong! optional bool suppress_monetization = 0x4E; - optional bool allow_background_playback = 0x4F; - optional bool interpret_restriction_using_geoip = 0x51; + optional bool interpret_restriction_using_geoip = 0x4F; + + optional bool allow_background_playback = 0x51; + repeated Availability availability = 0x52; optional string external_url = 0x53; optional OriginalAudio original_audio = 0x54; } diff --git a/protocol/src/metadata.rs b/protocol/src/metadata.rs index 7d38e02d..386213ab 100644 --- a/protocol/src/metadata.rs +++ b/protocol/src/metadata.rs @@ -1626,6 +1626,8 @@ pub struct Date { year: ::std::option::Option, month: ::std::option::Option, day: ::std::option::Option, + hour: ::std::option::Option, + minute: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -1698,6 +1700,44 @@ impl Date { pub fn set_day(&mut self, v: i32) { self.day = ::std::option::Option::Some(v); } + + // optional sint32 hour = 4; + + + pub fn get_hour(&self) -> i32 { + self.hour.unwrap_or(0) + } + pub fn clear_hour(&mut self) { + self.hour = ::std::option::Option::None; + } + + pub fn has_hour(&self) -> bool { + self.hour.is_some() + } + + // Param is passed by value, moved + pub fn set_hour(&mut self, v: i32) { + self.hour = ::std::option::Option::Some(v); + } + + // optional sint32 minute = 5; + + + pub fn get_minute(&self) -> i32 { + self.minute.unwrap_or(0) + } + pub fn clear_minute(&mut self) { + self.minute = ::std::option::Option::None; + } + + pub fn has_minute(&self) -> bool { + self.minute.is_some() + } + + // Param is passed by value, moved + pub fn set_minute(&mut self, v: i32) { + self.minute = ::std::option::Option::Some(v); + } } impl ::protobuf::Message for Date { @@ -1730,6 +1770,20 @@ impl ::protobuf::Message for Date { let tmp = is.read_sint32()?; self.day = ::std::option::Option::Some(tmp); }, + 4 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.hour = ::std::option::Option::Some(tmp); + }, + 5 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.minute = ::std::option::Option::Some(tmp); + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -1751,6 +1805,12 @@ impl ::protobuf::Message for Date { if let Some(v) = self.day { my_size += ::protobuf::rt::value_varint_zigzag_size(3, v); } + if let Some(v) = self.hour { + my_size += ::protobuf::rt::value_varint_zigzag_size(4, v); + } + if let Some(v) = self.minute { + my_size += ::protobuf::rt::value_varint_zigzag_size(5, v); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -1766,6 +1826,12 @@ impl ::protobuf::Message for Date { if let Some(v) = self.day { os.write_sint32(3, v)?; } + if let Some(v) = self.hour { + os.write_sint32(4, v)?; + } + if let Some(v) = self.minute { + os.write_sint32(5, v)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -1823,6 +1889,16 @@ impl ::protobuf::Message for Date { |m: &Date| { &m.day }, |m: &mut Date| { &mut m.day }, )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "hour", + |m: &Date| { &m.hour }, + |m: &mut Date| { &mut m.hour }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "minute", + |m: &Date| { &m.minute }, + |m: &mut Date| { &mut m.minute }, + )); ::protobuf::reflect::MessageDescriptor::new::( "Date", fields, @@ -1848,6 +1924,8 @@ impl ::protobuf::Clear for Date { self.year = ::std::option::Option::None; self.month = ::std::option::Option::None; self.day = ::std::option::Option::None; + self.hour = ::std::option::Option::None; + self.minute = ::std::option::Option::None; self.unknown_fields.clear(); } } @@ -5042,6 +5120,7 @@ impl ::protobuf::reflect::ProtobufValue for Copyright_Type { #[derive(PartialEq,Clone,Default)] pub struct Restriction { // message fields + catalogue: ::std::vec::Vec, countries_allowed: ::protobuf::SingularField<::std::string::String>, countries_forbidden: ::protobuf::SingularField<::std::string::String>, typ: ::std::option::Option, @@ -5062,6 +5141,31 @@ impl Restriction { ::std::default::Default::default() } + // repeated .Restriction.Catalogue catalogue = 1; + + + pub fn get_catalogue(&self) -> &[Restriction_Catalogue] { + &self.catalogue + } + pub fn clear_catalogue(&mut self) { + self.catalogue.clear(); + } + + // Param is passed by value, moved + pub fn set_catalogue(&mut self, v: ::std::vec::Vec) { + self.catalogue = v; + } + + // Mutable pointer to the field. + pub fn mut_catalogue(&mut self) -> &mut ::std::vec::Vec { + &mut self.catalogue + } + + // Take field + pub fn take_catalogue(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.catalogue, ::std::vec::Vec::new()) + } + // optional string countries_allowed = 2; @@ -5188,6 +5292,9 @@ impl ::protobuf::Message for Restriction { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { + 1 => { + ::protobuf::rt::read_repeated_enum_with_unknown_fields_into(wire_type, is, &mut self.catalogue, 1, &mut self.unknown_fields)? + }, 2 => { ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.countries_allowed)?; }, @@ -5212,6 +5319,9 @@ impl ::protobuf::Message for Restriction { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; + for value in &self.catalogue { + my_size += ::protobuf::rt::enum_size(1, *value); + }; if let Some(ref v) = self.countries_allowed.as_ref() { my_size += ::protobuf::rt::string_size(2, &v); } @@ -5230,6 +5340,9 @@ impl ::protobuf::Message for Restriction { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + for v in &self.catalogue { + os.write_enum(1, v.value())?; + }; if let Some(ref v) = self.countries_allowed.as_ref() { os.write_string(2, &v)?; } @@ -5284,6 +5397,11 @@ impl ::protobuf::Message for Restriction { unsafe { descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_vec_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "catalogue", + |m: &Restriction| { &m.catalogue }, + |m: &mut Restriction| { &mut m.catalogue }, + )); fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "countries_allowed", |m: &Restriction| { &m.countries_allowed }, @@ -5326,6 +5444,7 @@ impl ::protobuf::Message for Restriction { impl ::protobuf::Clear for Restriction { fn clear(&mut self) { + self.catalogue.clear(); self.countries_allowed.clear(); self.countries_forbidden.clear(); self.typ = ::std::option::Option::None; @@ -5346,6 +5465,70 @@ impl ::protobuf::reflect::ProtobufValue for Restriction { } } +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum Restriction_Catalogue { + AD = 0, + SUBSCRIPTION = 1, + CATALOGUE_ALL = 2, + SHUFFLE = 3, + COMMERCIAL = 4, +} + +impl ::protobuf::ProtobufEnum for Restriction_Catalogue { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(Restriction_Catalogue::AD), + 1 => ::std::option::Option::Some(Restriction_Catalogue::SUBSCRIPTION), + 2 => ::std::option::Option::Some(Restriction_Catalogue::CATALOGUE_ALL), + 3 => ::std::option::Option::Some(Restriction_Catalogue::SHUFFLE), + 4 => ::std::option::Option::Some(Restriction_Catalogue::COMMERCIAL), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [Restriction_Catalogue] = &[ + Restriction_Catalogue::AD, + Restriction_Catalogue::SUBSCRIPTION, + Restriction_Catalogue::CATALOGUE_ALL, + Restriction_Catalogue::SHUFFLE, + Restriction_Catalogue::COMMERCIAL, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, + }; + unsafe { + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new("Restriction_Catalogue", file_descriptor_proto()) + }) + } + } +} + +impl ::std::marker::Copy for Restriction_Catalogue { +} + +impl ::std::default::Default for Restriction_Catalogue { + fn default() -> Self { + Restriction_Catalogue::AD + } +} + +impl ::protobuf::reflect::ProtobufValue for Restriction_Catalogue { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum Restriction_Type { STREAMING = 0, @@ -5398,6 +5581,231 @@ impl ::protobuf::reflect::ProtobufValue for Restriction_Type { } } +#[derive(PartialEq,Clone,Default)] +pub struct Availability { + // message fields + catalogue_str: ::protobuf::RepeatedField<::std::string::String>, + start: ::protobuf::SingularPtrField, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a Availability { + fn default() -> &'a Availability { + ::default_instance() + } +} + +impl Availability { + pub fn new() -> Availability { + ::std::default::Default::default() + } + + // repeated string catalogue_str = 1; + + + pub fn get_catalogue_str(&self) -> &[::std::string::String] { + &self.catalogue_str + } + pub fn clear_catalogue_str(&mut self) { + self.catalogue_str.clear(); + } + + // Param is passed by value, moved + pub fn set_catalogue_str(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { + self.catalogue_str = v; + } + + // Mutable pointer to the field. + pub fn mut_catalogue_str(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { + &mut self.catalogue_str + } + + // Take field + pub fn take_catalogue_str(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { + ::std::mem::replace(&mut self.catalogue_str, ::protobuf::RepeatedField::new()) + } + + // optional .Date start = 2; + + + pub fn get_start(&self) -> &Date { + self.start.as_ref().unwrap_or_else(|| Date::default_instance()) + } + pub fn clear_start(&mut self) { + self.start.clear(); + } + + pub fn has_start(&self) -> bool { + self.start.is_some() + } + + // Param is passed by value, moved + pub fn set_start(&mut self, v: Date) { + self.start = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_start(&mut self) -> &mut Date { + if self.start.is_none() { + self.start.set_default(); + } + self.start.as_mut().unwrap() + } + + // Take field + pub fn take_start(&mut self) -> Date { + self.start.take().unwrap_or_else(|| Date::new()) + } +} + +impl ::protobuf::Message for Availability { + fn is_initialized(&self) -> bool { + for v in &self.start { + if !v.is_initialized() { + return false; + } + }; + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.catalogue_str)?; + }, + 2 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.start)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + for value in &self.catalogue_str { + my_size += ::protobuf::rt::string_size(1, &value); + }; + if let Some(ref v) = self.start.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + for v in &self.catalogue_str { + os.write_string(1, &v)?; + }; + if let Some(ref v) = self.start.as_ref() { + os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> Availability { + Availability::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, + }; + unsafe { + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "catalogue_str", + |m: &Availability| { &m.catalogue_str }, + |m: &mut Availability| { &mut m.catalogue_str }, + )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "start", + |m: &Availability| { &m.start }, + |m: &mut Availability| { &mut m.start }, + )); + ::protobuf::reflect::MessageDescriptor::new::( + "Availability", + fields, + file_descriptor_proto() + ) + }) + } + } + + fn default_instance() -> &'static Availability { + static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const Availability, + }; + unsafe { + instance.get(Availability::new) + } + } +} + +impl ::protobuf::Clear for Availability { + fn clear(&mut self) { + self.catalogue_str.clear(); + self.start.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for Availability { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Availability { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct SalePeriod { // message fields @@ -6225,126 +6633,63 @@ impl ::protobuf::reflect::ProtobufValue for AudioFile_Format { } #[derive(PartialEq,Clone,Default)] -pub struct PublishTime { +pub struct VideoFile { // message fields - year: ::std::option::Option, - month: ::std::option::Option, - day: ::std::option::Option, - minute: ::std::option::Option, - hour: ::std::option::Option, + file_id: ::protobuf::SingularField<::std::vec::Vec>, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, } -impl<'a> ::std::default::Default for &'a PublishTime { - fn default() -> &'a PublishTime { - ::default_instance() +impl<'a> ::std::default::Default for &'a VideoFile { + fn default() -> &'a VideoFile { + ::default_instance() } } -impl PublishTime { - pub fn new() -> PublishTime { +impl VideoFile { + pub fn new() -> VideoFile { ::std::default::Default::default() } - // optional sint32 year = 1; + // optional bytes file_id = 1; - pub fn get_year(&self) -> i32 { - self.year.unwrap_or(0) + pub fn get_file_id(&self) -> &[u8] { + match self.file_id.as_ref() { + Some(v) => &v, + None => &[], + } } - pub fn clear_year(&mut self) { - self.year = ::std::option::Option::None; + pub fn clear_file_id(&mut self) { + self.file_id.clear(); } - pub fn has_year(&self) -> bool { - self.year.is_some() + pub fn has_file_id(&self) -> bool { + self.file_id.is_some() } // Param is passed by value, moved - pub fn set_year(&mut self, v: i32) { - self.year = ::std::option::Option::Some(v); + pub fn set_file_id(&mut self, v: ::std::vec::Vec) { + self.file_id = ::protobuf::SingularField::some(v); } - // optional sint32 month = 2; - - - pub fn get_month(&self) -> i32 { - self.month.unwrap_or(0) - } - pub fn clear_month(&mut self) { - self.month = ::std::option::Option::None; + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_file_id(&mut self) -> &mut ::std::vec::Vec { + if self.file_id.is_none() { + self.file_id.set_default(); + } + self.file_id.as_mut().unwrap() } - pub fn has_month(&self) -> bool { - self.month.is_some() - } - - // Param is passed by value, moved - pub fn set_month(&mut self, v: i32) { - self.month = ::std::option::Option::Some(v); - } - - // optional sint32 day = 3; - - - pub fn get_day(&self) -> i32 { - self.day.unwrap_or(0) - } - pub fn clear_day(&mut self) { - self.day = ::std::option::Option::None; - } - - pub fn has_day(&self) -> bool { - self.day.is_some() - } - - // Param is passed by value, moved - pub fn set_day(&mut self, v: i32) { - self.day = ::std::option::Option::Some(v); - } - - // optional sint32 minute = 5; - - - pub fn get_minute(&self) -> i32 { - self.minute.unwrap_or(0) - } - pub fn clear_minute(&mut self) { - self.minute = ::std::option::Option::None; - } - - pub fn has_minute(&self) -> bool { - self.minute.is_some() - } - - // Param is passed by value, moved - pub fn set_minute(&mut self, v: i32) { - self.minute = ::std::option::Option::Some(v); - } - - // optional sint32 hour = 4; - - - pub fn get_hour(&self) -> i32 { - self.hour.unwrap_or(0) - } - pub fn clear_hour(&mut self) { - self.hour = ::std::option::Option::None; - } - - pub fn has_hour(&self) -> bool { - self.hour.is_some() - } - - // Param is passed by value, moved - pub fn set_hour(&mut self, v: i32) { - self.hour = ::std::option::Option::Some(v); + // Take field + pub fn take_file_id(&mut self) -> ::std::vec::Vec { + self.file_id.take().unwrap_or_else(|| ::std::vec::Vec::new()) } } -impl ::protobuf::Message for PublishTime { +impl ::protobuf::Message for VideoFile { fn is_initialized(&self) -> bool { true } @@ -6354,39 +6699,7 @@ impl ::protobuf::Message for PublishTime { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_sint32()?; - self.year = ::std::option::Option::Some(tmp); - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_sint32()?; - self.month = ::std::option::Option::Some(tmp); - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_sint32()?; - self.day = ::std::option::Option::Some(tmp); - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_sint32()?; - self.minute = ::std::option::Option::Some(tmp); - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_sint32()?; - self.hour = ::std::option::Option::Some(tmp); + ::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.file_id)?; }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; @@ -6400,20 +6713,8 @@ impl ::protobuf::Message for PublishTime { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if let Some(v) = self.year { - my_size += ::protobuf::rt::value_varint_zigzag_size(1, v); - } - if let Some(v) = self.month { - my_size += ::protobuf::rt::value_varint_zigzag_size(2, v); - } - if let Some(v) = self.day { - my_size += ::protobuf::rt::value_varint_zigzag_size(3, v); - } - if let Some(v) = self.minute { - my_size += ::protobuf::rt::value_varint_zigzag_size(5, v); - } - if let Some(v) = self.hour { - my_size += ::protobuf::rt::value_varint_zigzag_size(4, v); + if let Some(ref v) = self.file_id.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); @@ -6421,20 +6722,8 @@ impl ::protobuf::Message for PublishTime { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { - if let Some(v) = self.year { - os.write_sint32(1, v)?; - } - if let Some(v) = self.month { - os.write_sint32(2, v)?; - } - if let Some(v) = self.day { - os.write_sint32(3, v)?; - } - if let Some(v) = self.minute { - os.write_sint32(5, v)?; - } - if let Some(v) = self.hour { - os.write_sint32(4, v)?; + if let Some(ref v) = self.file_id.as_ref() { + os.write_bytes(1, &v)?; } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) @@ -6466,8 +6755,8 @@ impl ::protobuf::Message for PublishTime { Self::descriptor_static() } - fn new() -> PublishTime { - PublishTime::new() + fn new() -> VideoFile { + VideoFile::new() } fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { @@ -6478,33 +6767,13 @@ impl ::protobuf::Message for PublishTime { unsafe { descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( - "year", - |m: &PublishTime| { &m.year }, - |m: &mut PublishTime| { &mut m.year }, + fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "file_id", + |m: &VideoFile| { &m.file_id }, + |m: &mut VideoFile| { &mut m.file_id }, )); - fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( - "month", - |m: &PublishTime| { &m.month }, - |m: &mut PublishTime| { &mut m.month }, - )); - fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( - "day", - |m: &PublishTime| { &m.day }, - |m: &mut PublishTime| { &mut m.day }, - )); - fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( - "minute", - |m: &PublishTime| { &m.minute }, - |m: &mut PublishTime| { &mut m.minute }, - )); - fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( - "hour", - |m: &PublishTime| { &m.hour }, - |m: &mut PublishTime| { &mut m.hour }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "PublishTime", + ::protobuf::reflect::MessageDescriptor::new::( + "VideoFile", fields, file_descriptor_proto() ) @@ -6512,35 +6781,31 @@ impl ::protobuf::Message for PublishTime { } } - fn default_instance() -> &'static PublishTime { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { + fn default_instance() -> &'static VideoFile { + static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const PublishTime, + ptr: 0 as *const VideoFile, }; unsafe { - instance.get(PublishTime::new) + instance.get(VideoFile::new) } } } -impl ::protobuf::Clear for PublishTime { +impl ::protobuf::Clear for VideoFile { fn clear(&mut self) { - self.year = ::std::option::Option::None; - self.month = ::std::option::Option::None; - self.day = ::std::option::Option::None; - self.minute = ::std::option::Option::None; - self.hour = ::std::option::Option::None; + self.file_id.clear(); self.unknown_fields.clear(); } } -impl ::std::fmt::Debug for PublishTime { +impl ::std::fmt::Debug for VideoFile { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } -impl ::protobuf::reflect::ProtobufValue for PublishTime { +impl ::protobuf::reflect::ProtobufValue for VideoFile { fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { ::protobuf::reflect::ProtobufValueRef::Message(self) } @@ -6551,19 +6816,23 @@ pub struct Show { // message fields gid: ::protobuf::SingularField<::std::vec::Vec>, name: ::protobuf::SingularField<::std::string::String>, - episode: ::protobuf::RepeatedField, description: ::protobuf::SingularField<::std::string::String>, + deprecated_popularity: ::std::option::Option, publisher: ::protobuf::SingularField<::std::string::String>, language: ::protobuf::SingularField<::std::string::String>, explicit: ::std::option::Option, covers: ::protobuf::SingularPtrField, + episode: ::protobuf::RepeatedField, + copyright: ::protobuf::RepeatedField, restriction: ::protobuf::RepeatedField, - media_type: ::std::option::Option, - consumption_order: ::std::option::Option, + keyword: ::protobuf::RepeatedField<::std::string::String>, + media_type: ::std::option::Option, + consumption_order: ::std::option::Option, interpret_restriction_using_geoip: ::std::option::Option, + availability: ::protobuf::RepeatedField, country_of_origin: ::protobuf::SingularField<::std::string::String>, categories: ::protobuf::RepeatedField, - passthrough: ::std::option::Option, + passthrough: ::std::option::Option, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -6652,31 +6921,6 @@ impl Show { self.name.take().unwrap_or_else(|| ::std::string::String::new()) } - // repeated .Episode episode = 70; - - - pub fn get_episode(&self) -> &[Episode] { - &self.episode - } - pub fn clear_episode(&mut self) { - self.episode.clear(); - } - - // Param is passed by value, moved - pub fn set_episode(&mut self, v: ::protobuf::RepeatedField) { - self.episode = v; - } - - // Mutable pointer to the field. - pub fn mut_episode(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.episode - } - - // Take field - pub fn take_episode(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.episode, ::protobuf::RepeatedField::new()) - } - // optional string description = 64; @@ -6713,6 +6957,25 @@ impl Show { self.description.take().unwrap_or_else(|| ::std::string::String::new()) } + // optional sint32 deprecated_popularity = 65; + + + pub fn get_deprecated_popularity(&self) -> i32 { + self.deprecated_popularity.unwrap_or(0) + } + pub fn clear_deprecated_popularity(&mut self) { + self.deprecated_popularity = ::std::option::Option::None; + } + + pub fn has_deprecated_popularity(&self) -> bool { + self.deprecated_popularity.is_some() + } + + // Param is passed by value, moved + pub fn set_deprecated_popularity(&mut self, v: i32) { + self.deprecated_popularity = ::std::option::Option::Some(v); + } + // optional string publisher = 66; @@ -6837,6 +7100,56 @@ impl Show { self.covers.take().unwrap_or_else(|| ImageGroup::new()) } + // repeated .Episode episode = 70; + + + pub fn get_episode(&self) -> &[Episode] { + &self.episode + } + pub fn clear_episode(&mut self) { + self.episode.clear(); + } + + // Param is passed by value, moved + pub fn set_episode(&mut self, v: ::protobuf::RepeatedField) { + self.episode = v; + } + + // Mutable pointer to the field. + pub fn mut_episode(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.episode + } + + // Take field + pub fn take_episode(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.episode, ::protobuf::RepeatedField::new()) + } + + // repeated .Copyright copyright = 71; + + + pub fn get_copyright(&self) -> &[Copyright] { + &self.copyright + } + pub fn clear_copyright(&mut self) { + self.copyright.clear(); + } + + // Param is passed by value, moved + pub fn set_copyright(&mut self, v: ::protobuf::RepeatedField) { + self.copyright = v; + } + + // Mutable pointer to the field. + pub fn mut_copyright(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.copyright + } + + // Take field + pub fn take_copyright(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.copyright, ::protobuf::RepeatedField::new()) + } + // repeated .Restriction restriction = 72; @@ -6862,11 +7175,36 @@ impl Show { ::std::mem::replace(&mut self.restriction, ::protobuf::RepeatedField::new()) } - // optional .MediaType media_type = 74; + // repeated string keyword = 73; - pub fn get_media_type(&self) -> MediaType { - self.media_type.unwrap_or(MediaType::MIXED) + pub fn get_keyword(&self) -> &[::std::string::String] { + &self.keyword + } + pub fn clear_keyword(&mut self) { + self.keyword.clear(); + } + + // Param is passed by value, moved + pub fn set_keyword(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { + self.keyword = v; + } + + // Mutable pointer to the field. + pub fn mut_keyword(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { + &mut self.keyword + } + + // Take field + pub fn take_keyword(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { + ::std::mem::replace(&mut self.keyword, ::protobuf::RepeatedField::new()) + } + + // optional .Show.MediaType media_type = 74; + + + pub fn get_media_type(&self) -> Show_MediaType { + self.media_type.unwrap_or(Show_MediaType::MIXED) } pub fn clear_media_type(&mut self) { self.media_type = ::std::option::Option::None; @@ -6877,15 +7215,15 @@ impl Show { } // Param is passed by value, moved - pub fn set_media_type(&mut self, v: MediaType) { + pub fn set_media_type(&mut self, v: Show_MediaType) { self.media_type = ::std::option::Option::Some(v); } - // optional .ConsumptionOrder consumption_order = 75; + // optional .Show.ConsumptionOrder consumption_order = 75; - pub fn get_consumption_order(&self) -> ConsumptionOrder { - self.consumption_order.unwrap_or(ConsumptionOrder::SEQUENTIAL) + pub fn get_consumption_order(&self) -> Show_ConsumptionOrder { + self.consumption_order.unwrap_or(Show_ConsumptionOrder::SEQUENTIAL) } pub fn clear_consumption_order(&mut self) { self.consumption_order = ::std::option::Option::None; @@ -6896,7 +7234,7 @@ impl Show { } // Param is passed by value, moved - pub fn set_consumption_order(&mut self, v: ConsumptionOrder) { + pub fn set_consumption_order(&mut self, v: Show_ConsumptionOrder) { self.consumption_order = ::std::option::Option::Some(v); } @@ -6919,6 +7257,31 @@ impl Show { self.interpret_restriction_using_geoip = ::std::option::Option::Some(v); } + // repeated .Availability availability = 78; + + + pub fn get_availability(&self) -> &[Availability] { + &self.availability + } + pub fn clear_availability(&mut self) { + self.availability.clear(); + } + + // Param is passed by value, moved + pub fn set_availability(&mut self, v: ::protobuf::RepeatedField) { + self.availability = v; + } + + // Mutable pointer to the field. + pub fn mut_availability(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.availability + } + + // Take field + pub fn take_availability(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.availability, ::protobuf::RepeatedField::new()) + } + // optional string country_of_origin = 79; @@ -6980,11 +7343,11 @@ impl Show { ::std::mem::replace(&mut self.categories, ::protobuf::RepeatedField::new()) } - // optional .PassthroughEnum passthrough = 81; + // optional .Show.PassthroughEnum passthrough = 81; - pub fn get_passthrough(&self) -> PassthroughEnum { - self.passthrough.unwrap_or(PassthroughEnum::UNKNOWN) + pub fn get_passthrough(&self) -> Show_PassthroughEnum { + self.passthrough.unwrap_or(Show_PassthroughEnum::UNKNOWN) } pub fn clear_passthrough(&mut self) { self.passthrough = ::std::option::Option::None; @@ -6995,28 +7358,38 @@ impl Show { } // Param is passed by value, moved - pub fn set_passthrough(&mut self, v: PassthroughEnum) { + pub fn set_passthrough(&mut self, v: Show_PassthroughEnum) { self.passthrough = ::std::option::Option::Some(v); } } impl ::protobuf::Message for Show { fn is_initialized(&self) -> bool { - for v in &self.episode { - if !v.is_initialized() { - return false; - } - }; for v in &self.covers { if !v.is_initialized() { return false; } }; + for v in &self.episode { + if !v.is_initialized() { + return false; + } + }; + for v in &self.copyright { + if !v.is_initialized() { + return false; + } + }; for v in &self.restriction { if !v.is_initialized() { return false; } }; + for v in &self.availability { + if !v.is_initialized() { + return false; + } + }; for v in &self.categories { if !v.is_initialized() { return false; @@ -7035,12 +7408,16 @@ impl ::protobuf::Message for Show { 2 => { ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.name)?; }, - 70 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.episode)?; - }, 64 => { ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.description)?; }, + 65 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.deprecated_popularity = ::std::option::Option::Some(tmp); + }, 66 => { ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.publisher)?; }, @@ -7057,9 +7434,18 @@ impl ::protobuf::Message for Show { 69 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.covers)?; }, + 70 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.episode)?; + }, + 71 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.copyright)?; + }, 72 => { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.restriction)?; }, + 73 => { + ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.keyword)?; + }, 74 => { ::protobuf::rt::read_proto2_enum_with_unknown_fields_into(wire_type, is, &mut self.media_type, 74, &mut self.unknown_fields)? }, @@ -7073,6 +7459,9 @@ impl ::protobuf::Message for Show { let tmp = is.read_bool()?; self.interpret_restriction_using_geoip = ::std::option::Option::Some(tmp); }, + 78 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.availability)?; + }, 79 => { ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.country_of_origin)?; }, @@ -7100,13 +7489,12 @@ impl ::protobuf::Message for Show { if let Some(ref v) = self.name.as_ref() { my_size += ::protobuf::rt::string_size(2, &v); } - for value in &self.episode { - let len = value.compute_size(); - my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }; if let Some(ref v) = self.description.as_ref() { my_size += ::protobuf::rt::string_size(64, &v); } + if let Some(v) = self.deprecated_popularity { + my_size += ::protobuf::rt::value_varint_zigzag_size(65, v); + } if let Some(ref v) = self.publisher.as_ref() { my_size += ::protobuf::rt::string_size(66, &v); } @@ -7120,10 +7508,21 @@ impl ::protobuf::Message for Show { let len = v.compute_size(); my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } + for value in &self.episode { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.copyright { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; for value in &self.restriction { let len = value.compute_size(); my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; + for value in &self.keyword { + my_size += ::protobuf::rt::string_size(73, &value); + }; if let Some(v) = self.media_type { my_size += ::protobuf::rt::enum_size(74, v); } @@ -7133,6 +7532,10 @@ impl ::protobuf::Message for Show { if let Some(v) = self.interpret_restriction_using_geoip { my_size += 3; } + for value in &self.availability { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; if let Some(ref v) = self.country_of_origin.as_ref() { my_size += ::protobuf::rt::string_size(79, &v); } @@ -7155,14 +7558,12 @@ impl ::protobuf::Message for Show { if let Some(ref v) = self.name.as_ref() { os.write_string(2, &v)?; } - for v in &self.episode { - os.write_tag(70, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }; if let Some(ref v) = self.description.as_ref() { os.write_string(64, &v)?; } + if let Some(v) = self.deprecated_popularity { + os.write_sint32(65, v)?; + } if let Some(ref v) = self.publisher.as_ref() { os.write_string(66, &v)?; } @@ -7177,11 +7578,24 @@ impl ::protobuf::Message for Show { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } + for v in &self.episode { + os.write_tag(70, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.copyright { + os.write_tag(71, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; for v in &self.restriction { os.write_tag(72, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; + for v in &self.keyword { + os.write_string(73, &v)?; + }; if let Some(v) = self.media_type { os.write_enum(74, v.value())?; } @@ -7191,6 +7605,11 @@ impl ::protobuf::Message for Show { if let Some(v) = self.interpret_restriction_using_geoip { os.write_bool(76, v)?; } + for v in &self.availability { + os.write_tag(78, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; if let Some(ref v) = self.country_of_origin.as_ref() { os.write_string(79, &v)?; } @@ -7254,16 +7673,16 @@ impl ::protobuf::Message for Show { |m: &Show| { &m.name }, |m: &mut Show| { &mut m.name }, )); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "episode", - |m: &Show| { &m.episode }, - |m: &mut Show| { &mut m.episode }, - )); fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "description", |m: &Show| { &m.description }, |m: &mut Show| { &mut m.description }, )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "deprecated_popularity", + |m: &Show| { &m.deprecated_popularity }, + |m: &mut Show| { &mut m.deprecated_popularity }, + )); fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "publisher", |m: &Show| { &m.publisher }, @@ -7284,17 +7703,32 @@ impl ::protobuf::Message for Show { |m: &Show| { &m.covers }, |m: &mut Show| { &mut m.covers }, )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "episode", + |m: &Show| { &m.episode }, + |m: &mut Show| { &mut m.episode }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "copyright", + |m: &Show| { &m.copyright }, + |m: &mut Show| { &mut m.copyright }, + )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "restriction", |m: &Show| { &m.restriction }, |m: &mut Show| { &mut m.restriction }, )); - fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "keyword", + |m: &Show| { &m.keyword }, + |m: &mut Show| { &mut m.keyword }, + )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "media_type", |m: &Show| { &m.media_type }, |m: &mut Show| { &mut m.media_type }, )); - fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "consumption_order", |m: &Show| { &m.consumption_order }, |m: &mut Show| { &mut m.consumption_order }, @@ -7304,6 +7738,11 @@ impl ::protobuf::Message for Show { |m: &Show| { &m.interpret_restriction_using_geoip }, |m: &mut Show| { &mut m.interpret_restriction_using_geoip }, )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "availability", + |m: &Show| { &m.availability }, + |m: &mut Show| { &mut m.availability }, + )); fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "country_of_origin", |m: &Show| { &m.country_of_origin }, @@ -7314,7 +7753,7 @@ impl ::protobuf::Message for Show { |m: &Show| { &m.categories }, |m: &mut Show| { &mut m.categories }, )); - fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "passthrough", |m: &Show| { &m.passthrough }, |m: &mut Show| { &mut m.passthrough }, @@ -7343,16 +7782,20 @@ impl ::protobuf::Clear for Show { fn clear(&mut self) { self.gid.clear(); self.name.clear(); - self.episode.clear(); self.description.clear(); + self.deprecated_popularity = ::std::option::Option::None; self.publisher.clear(); self.language.clear(); self.explicit = ::std::option::Option::None; self.covers.clear(); + self.episode.clear(); + self.copyright.clear(); self.restriction.clear(); + self.keyword.clear(); self.media_type = ::std::option::Option::None; self.consumption_order = ::std::option::Option::None; self.interpret_restriction_using_geoip = ::std::option::Option::None; + self.availability.clear(); self.country_of_origin.clear(); self.categories.clear(); self.passthrough = ::std::option::Option::None; @@ -7372,6 +7815,181 @@ impl ::protobuf::reflect::ProtobufValue for Show { } } +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum Show_MediaType { + MIXED = 0, + AUDIO = 1, + VIDEO = 2, +} + +impl ::protobuf::ProtobufEnum for Show_MediaType { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(Show_MediaType::MIXED), + 1 => ::std::option::Option::Some(Show_MediaType::AUDIO), + 2 => ::std::option::Option::Some(Show_MediaType::VIDEO), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [Show_MediaType] = &[ + Show_MediaType::MIXED, + Show_MediaType::AUDIO, + Show_MediaType::VIDEO, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, + }; + unsafe { + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new("Show_MediaType", file_descriptor_proto()) + }) + } + } +} + +impl ::std::marker::Copy for Show_MediaType { +} + +impl ::std::default::Default for Show_MediaType { + fn default() -> Self { + Show_MediaType::MIXED + } +} + +impl ::protobuf::reflect::ProtobufValue for Show_MediaType { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum Show_ConsumptionOrder { + SEQUENTIAL = 1, + EPISODIC = 2, + RECENT = 3, +} + +impl ::protobuf::ProtobufEnum for Show_ConsumptionOrder { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 1 => ::std::option::Option::Some(Show_ConsumptionOrder::SEQUENTIAL), + 2 => ::std::option::Option::Some(Show_ConsumptionOrder::EPISODIC), + 3 => ::std::option::Option::Some(Show_ConsumptionOrder::RECENT), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [Show_ConsumptionOrder] = &[ + Show_ConsumptionOrder::SEQUENTIAL, + Show_ConsumptionOrder::EPISODIC, + Show_ConsumptionOrder::RECENT, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, + }; + unsafe { + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new("Show_ConsumptionOrder", file_descriptor_proto()) + }) + } + } +} + +impl ::std::marker::Copy for Show_ConsumptionOrder { +} + +// Note, `Default` is implemented although default value is not 0 +impl ::std::default::Default for Show_ConsumptionOrder { + fn default() -> Self { + Show_ConsumptionOrder::SEQUENTIAL + } +} + +impl ::protobuf::reflect::ProtobufValue for Show_ConsumptionOrder { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum Show_PassthroughEnum { + UNKNOWN = 0, + NONE = 1, + ALLOWED = 2, +} + +impl ::protobuf::ProtobufEnum for Show_PassthroughEnum { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(Show_PassthroughEnum::UNKNOWN), + 1 => ::std::option::Option::Some(Show_PassthroughEnum::NONE), + 2 => ::std::option::Option::Some(Show_PassthroughEnum::ALLOWED), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [Show_PassthroughEnum] = &[ + Show_PassthroughEnum::UNKNOWN, + Show_PassthroughEnum::NONE, + Show_PassthroughEnum::ALLOWED, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, + }; + unsafe { + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new("Show_PassthroughEnum", file_descriptor_proto()) + }) + } + } +} + +impl ::std::marker::Copy for Show_PassthroughEnum { +} + +impl ::std::default::Default for Show_PassthroughEnum { + fn default() -> Self { + Show_PassthroughEnum::UNKNOWN + } +} + +impl ::protobuf::reflect::ProtobufValue for Show_PassthroughEnum { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) + } +} + #[derive(PartialEq,Clone,Default)] pub struct Episode { // message fields @@ -7381,16 +7999,23 @@ pub struct Episode { popularity: ::std::option::Option, file: ::protobuf::RepeatedField, description: ::protobuf::SingularField<::std::string::String>, + number: ::std::option::Option, publish_time: ::protobuf::SingularPtrField, + deprecated_popularity: ::std::option::Option, covers: ::protobuf::SingularPtrField, language: ::protobuf::SingularField<::std::string::String>, explicit: ::std::option::Option, show: ::protobuf::SingularPtrField, - preview: ::protobuf::RepeatedField, + video: ::protobuf::RepeatedField, + video_preview: ::protobuf::RepeatedField, + audio_preview: ::protobuf::RepeatedField, restriction: ::protobuf::RepeatedField, + freeze_frame: ::protobuf::SingularPtrField, + keyword: ::protobuf::RepeatedField<::std::string::String>, suppress_monetization: ::std::option::Option, - allow_background_playback: ::std::option::Option, interpret_restriction_using_geoip: ::std::option::Option, + allow_background_playback: ::std::option::Option, + availability: ::protobuf::RepeatedField, external_url: ::protobuf::SingularField<::std::string::String>, original_audio: ::protobuf::SingularPtrField, // special fields @@ -7580,6 +8205,25 @@ impl Episode { self.description.take().unwrap_or_else(|| ::std::string::String::new()) } + // optional sint32 number = 65; + + + pub fn get_number(&self) -> i32 { + self.number.unwrap_or(0) + } + pub fn clear_number(&mut self) { + self.number = ::std::option::Option::None; + } + + pub fn has_number(&self) -> bool { + self.number.is_some() + } + + // Param is passed by value, moved + pub fn set_number(&mut self, v: i32) { + self.number = ::std::option::Option::Some(v); + } + // optional .Date publish_time = 66; @@ -7613,6 +8257,25 @@ impl Episode { self.publish_time.take().unwrap_or_else(|| Date::new()) } + // optional sint32 deprecated_popularity = 67; + + + pub fn get_deprecated_popularity(&self) -> i32 { + self.deprecated_popularity.unwrap_or(0) + } + pub fn clear_deprecated_popularity(&mut self) { + self.deprecated_popularity = ::std::option::Option::None; + } + + pub fn has_deprecated_popularity(&self) -> bool { + self.deprecated_popularity.is_some() + } + + // Param is passed by value, moved + pub fn set_deprecated_popularity(&mut self, v: i32) { + self.deprecated_popularity = ::std::option::Option::Some(v); + } + // optional .ImageGroup covers = 68; @@ -7734,29 +8397,79 @@ impl Episode { self.show.take().unwrap_or_else(|| Show::new()) } - // repeated .AudioFile preview = 74; + // repeated .VideoFile video = 72; - pub fn get_preview(&self) -> &[AudioFile] { - &self.preview + pub fn get_video(&self) -> &[VideoFile] { + &self.video } - pub fn clear_preview(&mut self) { - self.preview.clear(); + pub fn clear_video(&mut self) { + self.video.clear(); } // Param is passed by value, moved - pub fn set_preview(&mut self, v: ::protobuf::RepeatedField) { - self.preview = v; + pub fn set_video(&mut self, v: ::protobuf::RepeatedField) { + self.video = v; } // Mutable pointer to the field. - pub fn mut_preview(&mut self) -> &mut ::protobuf::RepeatedField { - &mut self.preview + pub fn mut_video(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.video } // Take field - pub fn take_preview(&mut self) -> ::protobuf::RepeatedField { - ::std::mem::replace(&mut self.preview, ::protobuf::RepeatedField::new()) + pub fn take_video(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.video, ::protobuf::RepeatedField::new()) + } + + // repeated .VideoFile video_preview = 73; + + + pub fn get_video_preview(&self) -> &[VideoFile] { + &self.video_preview + } + pub fn clear_video_preview(&mut self) { + self.video_preview.clear(); + } + + // Param is passed by value, moved + pub fn set_video_preview(&mut self, v: ::protobuf::RepeatedField) { + self.video_preview = v; + } + + // Mutable pointer to the field. + pub fn mut_video_preview(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.video_preview + } + + // Take field + pub fn take_video_preview(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.video_preview, ::protobuf::RepeatedField::new()) + } + + // repeated .AudioFile audio_preview = 74; + + + pub fn get_audio_preview(&self) -> &[AudioFile] { + &self.audio_preview + } + pub fn clear_audio_preview(&mut self) { + self.audio_preview.clear(); + } + + // Param is passed by value, moved + pub fn set_audio_preview(&mut self, v: ::protobuf::RepeatedField) { + self.audio_preview = v; + } + + // Mutable pointer to the field. + pub fn mut_audio_preview(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.audio_preview + } + + // Take field + pub fn take_audio_preview(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.audio_preview, ::protobuf::RepeatedField::new()) } // repeated .Restriction restriction = 75; @@ -7784,6 +8497,64 @@ impl Episode { ::std::mem::replace(&mut self.restriction, ::protobuf::RepeatedField::new()) } + // optional .ImageGroup freeze_frame = 76; + + + pub fn get_freeze_frame(&self) -> &ImageGroup { + self.freeze_frame.as_ref().unwrap_or_else(|| ImageGroup::default_instance()) + } + pub fn clear_freeze_frame(&mut self) { + self.freeze_frame.clear(); + } + + pub fn has_freeze_frame(&self) -> bool { + self.freeze_frame.is_some() + } + + // Param is passed by value, moved + pub fn set_freeze_frame(&mut self, v: ImageGroup) { + self.freeze_frame = ::protobuf::SingularPtrField::some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_freeze_frame(&mut self) -> &mut ImageGroup { + if self.freeze_frame.is_none() { + self.freeze_frame.set_default(); + } + self.freeze_frame.as_mut().unwrap() + } + + // Take field + pub fn take_freeze_frame(&mut self) -> ImageGroup { + self.freeze_frame.take().unwrap_or_else(|| ImageGroup::new()) + } + + // repeated string keyword = 77; + + + pub fn get_keyword(&self) -> &[::std::string::String] { + &self.keyword + } + pub fn clear_keyword(&mut self) { + self.keyword.clear(); + } + + // Param is passed by value, moved + pub fn set_keyword(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { + self.keyword = v; + } + + // Mutable pointer to the field. + pub fn mut_keyword(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { + &mut self.keyword + } + + // Take field + pub fn take_keyword(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { + ::std::mem::replace(&mut self.keyword, ::protobuf::RepeatedField::new()) + } + // optional bool suppress_monetization = 78; @@ -7803,7 +8574,26 @@ impl Episode { self.suppress_monetization = ::std::option::Option::Some(v); } - // optional bool allow_background_playback = 79; + // optional bool interpret_restriction_using_geoip = 79; + + + pub fn get_interpret_restriction_using_geoip(&self) -> bool { + self.interpret_restriction_using_geoip.unwrap_or(false) + } + pub fn clear_interpret_restriction_using_geoip(&mut self) { + self.interpret_restriction_using_geoip = ::std::option::Option::None; + } + + pub fn has_interpret_restriction_using_geoip(&self) -> bool { + self.interpret_restriction_using_geoip.is_some() + } + + // Param is passed by value, moved + pub fn set_interpret_restriction_using_geoip(&mut self, v: bool) { + self.interpret_restriction_using_geoip = ::std::option::Option::Some(v); + } + + // optional bool allow_background_playback = 81; pub fn get_allow_background_playback(&self) -> bool { @@ -7822,23 +8612,29 @@ impl Episode { self.allow_background_playback = ::std::option::Option::Some(v); } - // optional bool interpret_restriction_using_geoip = 81; + // repeated .Availability availability = 82; - pub fn get_interpret_restriction_using_geoip(&self) -> bool { - self.interpret_restriction_using_geoip.unwrap_or(false) + pub fn get_availability(&self) -> &[Availability] { + &self.availability } - pub fn clear_interpret_restriction_using_geoip(&mut self) { - self.interpret_restriction_using_geoip = ::std::option::Option::None; - } - - pub fn has_interpret_restriction_using_geoip(&self) -> bool { - self.interpret_restriction_using_geoip.is_some() + pub fn clear_availability(&mut self) { + self.availability.clear(); } // Param is passed by value, moved - pub fn set_interpret_restriction_using_geoip(&mut self, v: bool) { - self.interpret_restriction_using_geoip = ::std::option::Option::Some(v); + pub fn set_availability(&mut self, v: ::protobuf::RepeatedField) { + self.availability = v; + } + + // Mutable pointer to the field. + pub fn mut_availability(&mut self) -> &mut ::protobuf::RepeatedField { + &mut self.availability + } + + // Take field + pub fn take_availability(&mut self) -> ::protobuf::RepeatedField { + ::std::mem::replace(&mut self.availability, ::protobuf::RepeatedField::new()) } // optional string external_url = 83; @@ -7933,7 +8729,17 @@ impl ::protobuf::Message for Episode { return false; } }; - for v in &self.preview { + for v in &self.video { + if !v.is_initialized() { + return false; + } + }; + for v in &self.video_preview { + if !v.is_initialized() { + return false; + } + }; + for v in &self.audio_preview { if !v.is_initialized() { return false; } @@ -7943,6 +8749,16 @@ impl ::protobuf::Message for Episode { return false; } }; + for v in &self.freeze_frame { + if !v.is_initialized() { + return false; + } + }; + for v in &self.availability { + if !v.is_initialized() { + return false; + } + }; for v in &self.original_audio { if !v.is_initialized() { return false; @@ -7981,9 +8797,23 @@ impl ::protobuf::Message for Episode { 64 => { ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.description)?; }, + 65 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.number = ::std::option::Option::Some(tmp); + }, 66 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.publish_time)?; }, + 67 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_sint32()?; + self.deprecated_popularity = ::std::option::Option::Some(tmp); + }, 68 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.covers)?; }, @@ -8000,12 +8830,24 @@ impl ::protobuf::Message for Episode { 71 => { ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.show)?; }, + 72 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.video)?; + }, + 73 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.video_preview)?; + }, 74 => { - ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.preview)?; + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.audio_preview)?; }, 75 => { ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.restriction)?; }, + 76 => { + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.freeze_frame)?; + }, + 77 => { + ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.keyword)?; + }, 78 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); @@ -8018,14 +8860,17 @@ impl ::protobuf::Message for Episode { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } let tmp = is.read_bool()?; - self.allow_background_playback = ::std::option::Option::Some(tmp); + self.interpret_restriction_using_geoip = ::std::option::Option::Some(tmp); }, 81 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } let tmp = is.read_bool()?; - self.interpret_restriction_using_geoip = ::std::option::Option::Some(tmp); + self.allow_background_playback = ::std::option::Option::Some(tmp); + }, + 82 => { + ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.availability)?; }, 83 => { ::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.external_url)?; @@ -8064,10 +8909,16 @@ impl ::protobuf::Message for Episode { if let Some(ref v) = self.description.as_ref() { my_size += ::protobuf::rt::string_size(64, &v); } + if let Some(v) = self.number { + my_size += ::protobuf::rt::value_varint_zigzag_size(65, v); + } if let Some(ref v) = self.publish_time.as_ref() { let len = v.compute_size(); my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } + if let Some(v) = self.deprecated_popularity { + my_size += ::protobuf::rt::value_varint_zigzag_size(67, v); + } if let Some(ref v) = self.covers.as_ref() { let len = v.compute_size(); my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; @@ -8082,7 +8933,15 @@ impl ::protobuf::Message for Episode { let len = v.compute_size(); my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } - for value in &self.preview { + for value in &self.video { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.video_preview { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; + for value in &self.audio_preview { let len = value.compute_size(); my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; @@ -8090,15 +8949,26 @@ impl ::protobuf::Message for Episode { let len = value.compute_size(); my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; }; - if let Some(v) = self.suppress_monetization { - my_size += 3; + if let Some(ref v) = self.freeze_frame.as_ref() { + let len = v.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } - if let Some(v) = self.allow_background_playback { + for value in &self.keyword { + my_size += ::protobuf::rt::string_size(77, &value); + }; + if let Some(v) = self.suppress_monetization { my_size += 3; } if let Some(v) = self.interpret_restriction_using_geoip { my_size += 3; } + if let Some(v) = self.allow_background_playback { + my_size += 3; + } + for value in &self.availability { + let len = value.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint32_size(len) + len; + }; if let Some(ref v) = self.external_url.as_ref() { my_size += ::protobuf::rt::string_size(83, &v); } @@ -8132,11 +9002,17 @@ impl ::protobuf::Message for Episode { if let Some(ref v) = self.description.as_ref() { os.write_string(64, &v)?; } + if let Some(v) = self.number { + os.write_sint32(65, v)?; + } if let Some(ref v) = self.publish_time.as_ref() { os.write_tag(66, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } + if let Some(v) = self.deprecated_popularity { + os.write_sint32(67, v)?; + } if let Some(ref v) = self.covers.as_ref() { os.write_tag(68, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; @@ -8153,7 +9029,17 @@ impl ::protobuf::Message for Episode { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; } - for v in &self.preview { + for v in &self.video { + os.write_tag(72, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.video_preview { + os.write_tag(73, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; + for v in &self.audio_preview { os.write_tag(74, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -8163,15 +9049,28 @@ impl ::protobuf::Message for Episode { os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; }; + if let Some(ref v) = self.freeze_frame.as_ref() { + os.write_tag(76, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + } + for v in &self.keyword { + os.write_string(77, &v)?; + }; if let Some(v) = self.suppress_monetization { os.write_bool(78, v)?; } - if let Some(v) = self.allow_background_playback { + if let Some(v) = self.interpret_restriction_using_geoip { os.write_bool(79, v)?; } - if let Some(v) = self.interpret_restriction_using_geoip { + if let Some(v) = self.allow_background_playback { os.write_bool(81, v)?; } + for v in &self.availability { + os.write_tag(82, ::protobuf::wire_format::WireTypeLengthDelimited)?; + os.write_raw_varint32(v.get_cached_size())?; + v.write_to_with_cached_sizes(os)?; + }; if let Some(ref v) = self.external_url.as_ref() { os.write_string(83, &v)?; } @@ -8252,11 +9151,21 @@ impl ::protobuf::Message for Episode { |m: &Episode| { &m.description }, |m: &mut Episode| { &mut m.description }, )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "number", + |m: &Episode| { &m.number }, + |m: &mut Episode| { &mut m.number }, + )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "publish_time", |m: &Episode| { &m.publish_time }, |m: &mut Episode| { &mut m.publish_time }, )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeSint32>( + "deprecated_popularity", + |m: &Episode| { &m.deprecated_popularity }, + |m: &mut Episode| { &mut m.deprecated_popularity }, + )); fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "covers", |m: &Episode| { &m.covers }, @@ -8277,30 +9186,55 @@ impl ::protobuf::Message for Episode { |m: &Episode| { &m.show }, |m: &mut Episode| { &mut m.show }, )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "video", + |m: &Episode| { &m.video }, + |m: &mut Episode| { &mut m.video }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "video_preview", + |m: &Episode| { &m.video_preview }, + |m: &mut Episode| { &mut m.video_preview }, + )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "preview", - |m: &Episode| { &m.preview }, - |m: &mut Episode| { &mut m.preview }, + "audio_preview", + |m: &Episode| { &m.audio_preview }, + |m: &mut Episode| { &mut m.audio_preview }, )); fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( "restriction", |m: &Episode| { &m.restriction }, |m: &mut Episode| { &mut m.restriction }, )); + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "freeze_frame", + |m: &Episode| { &m.freeze_frame }, + |m: &mut Episode| { &mut m.freeze_frame }, + )); + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "keyword", + |m: &Episode| { &m.keyword }, + |m: &mut Episode| { &mut m.keyword }, + )); fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "suppress_monetization", |m: &Episode| { &m.suppress_monetization }, |m: &mut Episode| { &mut m.suppress_monetization }, )); + fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "interpret_restriction_using_geoip", + |m: &Episode| { &m.interpret_restriction_using_geoip }, + |m: &mut Episode| { &mut m.interpret_restriction_using_geoip }, + )); fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( "allow_background_playback", |m: &Episode| { &m.allow_background_playback }, |m: &mut Episode| { &mut m.allow_background_playback }, )); - fields.push(::protobuf::reflect::accessor::make_option_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "interpret_restriction_using_geoip", - |m: &Episode| { &m.interpret_restriction_using_geoip }, - |m: &mut Episode| { &mut m.interpret_restriction_using_geoip }, + fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "availability", + |m: &Episode| { &m.availability }, + |m: &mut Episode| { &mut m.availability }, )); fields.push(::protobuf::reflect::accessor::make_singular_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "external_url", @@ -8340,16 +9274,23 @@ impl ::protobuf::Clear for Episode { self.popularity = ::std::option::Option::None; self.file.clear(); self.description.clear(); + self.number = ::std::option::Option::None; self.publish_time.clear(); + self.deprecated_popularity = ::std::option::Option::None; self.covers.clear(); self.language.clear(); self.explicit = ::std::option::Option::None; self.show.clear(); - self.preview.clear(); + self.video.clear(); + self.video_preview.clear(); + self.audio_preview.clear(); self.restriction.clear(); + self.freeze_frame.clear(); + self.keyword.clear(); self.suppress_monetization = ::std::option::Option::None; - self.allow_background_playback = ::std::option::Option::None; self.interpret_restriction_using_geoip = ::std::option::Option::None; + self.allow_background_playback = ::std::option::Option::None; + self.availability.clear(); self.external_url.clear(); self.original_audio.clear(); self.unknown_fields.clear(); @@ -8775,181 +9716,6 @@ impl ::protobuf::reflect::ProtobufValue for OriginalAudio { } } -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum ConsumptionOrder { - SEQUENTIAL = 1, - EPISODIC = 2, - RECENT = 3, -} - -impl ::protobuf::ProtobufEnum for ConsumptionOrder { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 1 => ::std::option::Option::Some(ConsumptionOrder::SEQUENTIAL), - 2 => ::std::option::Option::Some(ConsumptionOrder::EPISODIC), - 3 => ::std::option::Option::Some(ConsumptionOrder::RECENT), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [ConsumptionOrder] = &[ - ConsumptionOrder::SEQUENTIAL, - ConsumptionOrder::EPISODIC, - ConsumptionOrder::RECENT, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, - }; - unsafe { - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new("ConsumptionOrder", file_descriptor_proto()) - }) - } - } -} - -impl ::std::marker::Copy for ConsumptionOrder { -} - -// Note, `Default` is implemented although default value is not 0 -impl ::std::default::Default for ConsumptionOrder { - fn default() -> Self { - ConsumptionOrder::SEQUENTIAL - } -} - -impl ::protobuf::reflect::ProtobufValue for ConsumptionOrder { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum MediaType { - MIXED = 0, - AUDIO = 1, - VIDEO = 2, -} - -impl ::protobuf::ProtobufEnum for MediaType { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(MediaType::MIXED), - 1 => ::std::option::Option::Some(MediaType::AUDIO), - 2 => ::std::option::Option::Some(MediaType::VIDEO), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [MediaType] = &[ - MediaType::MIXED, - MediaType::AUDIO, - MediaType::VIDEO, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, - }; - unsafe { - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new("MediaType", file_descriptor_proto()) - }) - } - } -} - -impl ::std::marker::Copy for MediaType { -} - -impl ::std::default::Default for MediaType { - fn default() -> Self { - MediaType::MIXED - } -} - -impl ::protobuf::reflect::ProtobufValue for MediaType { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum PassthroughEnum { - UNKNOWN = 0, - NONE = 1, - ALLOWED = 2, -} - -impl ::protobuf::ProtobufEnum for PassthroughEnum { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(PassthroughEnum::UNKNOWN), - 1 => ::std::option::Option::Some(PassthroughEnum::NONE), - 2 => ::std::option::Option::Some(PassthroughEnum::ALLOWED), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [PassthroughEnum] = &[ - PassthroughEnum::UNKNOWN, - PassthroughEnum::NONE, - PassthroughEnum::ALLOWED, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, - }; - unsafe { - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new("PassthroughEnum", file_descriptor_proto()) - }) - } - } -} - -impl ::std::marker::Copy for PassthroughEnum { -} - -impl ::std::default::Default for PassthroughEnum { - fn default() -> Self { - PassthroughEnum::UNKNOWN - } -} - -impl ::protobuf::reflect::ProtobufValue for PassthroughEnum { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) - } -} - static file_descriptor_proto_data: &'static [u8] = b"\ \n\x0emetadata.proto\x12\0\"9\n\tTopTracks\x12\x11\n\x07country\x18\x01\ \x20\x01(\tB\0\x12\x17\n\x05track\x18\x02\x20\x03(\x0b2\x06.TrackB\0:\0\ @@ -8970,32 +9736,33 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x18\x0f\x20\x03(\x0b2\x07.ArtistB\0\x12!\n\x17is_portrait_album_cover\ \x18\x10\x20\x01(\x08B\0\x12%\n\x0eportrait_group\x18\x11\x20\x01(\x0b2\ \x0b.ImageGroupB\0:\0\"'\n\nAlbumGroup\x12\x17\n\x05album\x18\x01\x20\ - \x03(\x0b2\x06.AlbumB\0:\0\"8\n\x04Date\x12\x0e\n\x04year\x18\x01\x20\ + \x03(\x0b2\x06.AlbumB\0:\0\"Z\n\x04Date\x12\x0e\n\x04year\x18\x01\x20\ \x01(\x11B\0\x12\x0f\n\x05month\x18\x02\x20\x01(\x11B\0\x12\r\n\x03day\ - \x18\x03\x20\x01(\x11B\0:\0\"\xf7\x03\n\x05Album\x12\r\n\x03gid\x18\x01\ - \x20\x01(\x0cB\0\x12\x0e\n\x04name\x18\x02\x20\x01(\tB\0\x12\x19\n\x06ar\ - tist\x18\x03\x20\x03(\x0b2\x07.ArtistB\0\x12\x1a\n\x03typ\x18\x04\x20\ - \x01(\x0e2\x0b.Album.TypeB\0\x12\x0f\n\x05label\x18\x05\x20\x01(\tB\0\ - \x12\x15\n\x04date\x18\x06\x20\x01(\x0b2\x05.DateB\0\x12\x14\n\npopulari\ - ty\x18\x07\x20\x01(\x11B\0\x12\x0f\n\x05genre\x18\x08\x20\x03(\tB\0\x12\ - \x17\n\x05cover\x18\t\x20\x03(\x0b2\x06.ImageB\0\x12\"\n\x0bexternal_id\ - \x18\n\x20\x03(\x0b2\x0b.ExternalIdB\0\x12\x15\n\x04disc\x18\x0b\x20\x03\ - (\x0b2\x05.DiscB\0\x12\x10\n\x06review\x18\x0c\x20\x03(\tB\0\x12\x1f\n\t\ - copyright\x18\r\x20\x03(\x0b2\n.CopyrightB\0\x12#\n\x0brestriction\x18\ - \x0e\x20\x03(\x0b2\x0c.RestrictionB\0\x12\x19\n\x07related\x18\x0f\x20\ - \x03(\x0b2\x06.AlbumB\0\x12\"\n\x0bsale_period\x18\x10\x20\x03(\x0b2\x0b\ - .SalePeriodB\0\x12\"\n\x0bcover_group\x18\x11\x20\x01(\x0b2\x0b.ImageGro\ - upB\0\"8\n\x04Type\x12\t\n\x05ALBUM\x10\x01\x12\n\n\x06SINGLE\x10\x02\ - \x12\x0f\n\x0bCOMPILATION\x10\x03\x12\x06\n\x02EP\x10\x04\x1a\0:\0\"\x8a\ - \x03\n\x05Track\x12\r\n\x03gid\x18\x01\x20\x01(\x0cB\0\x12\x0e\n\x04name\ - \x18\x02\x20\x01(\tB\0\x12\x17\n\x05album\x18\x03\x20\x01(\x0b2\x06.Albu\ - mB\0\x12\x19\n\x06artist\x18\x04\x20\x03(\x0b2\x07.ArtistB\0\x12\x10\n\ - \x06number\x18\x05\x20\x01(\x11B\0\x12\x15\n\x0bdisc_number\x18\x06\x20\ - \x01(\x11B\0\x12\x12\n\x08duration\x18\x07\x20\x01(\x11B\0\x12\x14\n\npo\ - pularity\x18\x08\x20\x01(\x11B\0\x12\x12\n\x08explicit\x18\t\x20\x01(\ - \x08B\0\x12\"\n\x0bexternal_id\x18\n\x20\x03(\x0b2\x0b.ExternalIdB\0\x12\ - #\n\x0brestriction\x18\x0b\x20\x03(\x0b2\x0c.RestrictionB\0\x12\x1a\n\ - \x04file\x18\x0c\x20\x03(\x0b2\n.AudioFileB\0\x12\x1d\n\x0balternative\ + \x18\x03\x20\x01(\x11B\0\x12\x0e\n\x04hour\x18\x04\x20\x01(\x11B\0\x12\ + \x10\n\x06minute\x18\x05\x20\x01(\x11B\0:\0\"\xf7\x03\n\x05Album\x12\r\n\ + \x03gid\x18\x01\x20\x01(\x0cB\0\x12\x0e\n\x04name\x18\x02\x20\x01(\tB\0\ + \x12\x19\n\x06artist\x18\x03\x20\x03(\x0b2\x07.ArtistB\0\x12\x1a\n\x03ty\ + p\x18\x04\x20\x01(\x0e2\x0b.Album.TypeB\0\x12\x0f\n\x05label\x18\x05\x20\ + \x01(\tB\0\x12\x15\n\x04date\x18\x06\x20\x01(\x0b2\x05.DateB\0\x12\x14\n\ + \npopularity\x18\x07\x20\x01(\x11B\0\x12\x0f\n\x05genre\x18\x08\x20\x03(\ + \tB\0\x12\x17\n\x05cover\x18\t\x20\x03(\x0b2\x06.ImageB\0\x12\"\n\x0bext\ + ernal_id\x18\n\x20\x03(\x0b2\x0b.ExternalIdB\0\x12\x15\n\x04disc\x18\x0b\ + \x20\x03(\x0b2\x05.DiscB\0\x12\x10\n\x06review\x18\x0c\x20\x03(\tB\0\x12\ + \x1f\n\tcopyright\x18\r\x20\x03(\x0b2\n.CopyrightB\0\x12#\n\x0brestricti\ + on\x18\x0e\x20\x03(\x0b2\x0c.RestrictionB\0\x12\x19\n\x07related\x18\x0f\ + \x20\x03(\x0b2\x06.AlbumB\0\x12\"\n\x0bsale_period\x18\x10\x20\x03(\x0b2\ + \x0b.SalePeriodB\0\x12\"\n\x0bcover_group\x18\x11\x20\x01(\x0b2\x0b.Imag\ + eGroupB\0\"8\n\x04Type\x12\t\n\x05ALBUM\x10\x01\x12\n\n\x06SINGLE\x10\ + \x02\x12\x0f\n\x0bCOMPILATION\x10\x03\x12\x06\n\x02EP\x10\x04\x1a\0:\0\"\ + \x8a\x03\n\x05Track\x12\r\n\x03gid\x18\x01\x20\x01(\x0cB\0\x12\x0e\n\x04\ + name\x18\x02\x20\x01(\tB\0\x12\x17\n\x05album\x18\x03\x20\x01(\x0b2\x06.\ + AlbumB\0\x12\x19\n\x06artist\x18\x04\x20\x03(\x0b2\x07.ArtistB\0\x12\x10\ + \n\x06number\x18\x05\x20\x01(\x11B\0\x12\x15\n\x0bdisc_number\x18\x06\ + \x20\x01(\x11B\0\x12\x12\n\x08duration\x18\x07\x20\x01(\x11B\0\x12\x14\n\ + \npopularity\x18\x08\x20\x01(\x11B\0\x12\x12\n\x08explicit\x18\t\x20\x01\ + (\x08B\0\x12\"\n\x0bexternal_id\x18\n\x20\x03(\x0b2\x0b.ExternalIdB\0\ + \x12#\n\x0brestriction\x18\x0b\x20\x03(\x0b2\x0c.RestrictionB\0\x12\x1a\ + \n\x04file\x18\x0c\x20\x03(\x0b2\n.AudioFileB\0\x12\x1d\n\x0balternative\ \x18\r\x20\x03(\x0b2\x06.TrackB\0\x12\"\n\x0bsale_period\x18\x0e\x20\x03\ (\x0b2\x0b.SalePeriodB\0\x12\x1d\n\x07preview\x18\x0f\x20\x03(\x0b2\n.Au\ dioFileB\0:\0\"\x95\x01\n\x05Image\x12\x11\n\x07file_id\x18\x01\x20\x01(\ @@ -9011,14 +9778,19 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\x05track\x18\x03\x20\x03(\x0b2\x06.TrackB\0:\0\"U\n\tCopyright\x12\ \x1e\n\x03typ\x18\x01\x20\x01(\x0e2\x0f.Copyright.TypeB\0\x12\x0e\n\x04t\ ext\x18\x02\x20\x01(\tB\0\"\x16\n\x04Type\x12\x05\n\x01P\x10\0\x12\x05\n\ - \x01C\x10\x01\x1a\0:\0\"\x9f\x01\n\x0bRestriction\x12\x1b\n\x11countries\ - _allowed\x18\x02\x20\x01(\tB\0\x12\x1d\n\x13countries_forbidden\x18\x03\ + \x01C\x10\x01\x1a\0:\0\"\xa5\x02\n\x0bRestriction\x12+\n\tcatalogue\x18\ + \x01\x20\x03(\x0e2\x16.Restriction.CatalogueB\0\x12\x1b\n\x11countries_a\ + llowed\x18\x02\x20\x01(\tB\0\x12\x1d\n\x13countries_forbidden\x18\x03\ \x20\x01(\tB\0\x12\x20\n\x03typ\x18\x04\x20\x01(\x0e2\x11.Restriction.Ty\ - peB\0\x12\x17\n\rcatalogue_str\x18\x05\x20\x03(\tB\0\"\x17\n\x04Type\x12\ - \r\n\tSTREAMING\x10\0\x1a\0:\0\"a\n\nSalePeriod\x12#\n\x0brestriction\ - \x18\x01\x20\x03(\x0b2\x0c.RestrictionB\0\x12\x16\n\x05start\x18\x02\x20\ - \x01(\x0b2\x05.DateB\0\x12\x14\n\x03end\x18\x03\x20\x01(\x0b2\x05.DateB\ - \0:\0\"+\n\nExternalId\x12\r\n\x03typ\x18\x01\x20\x01(\tB\0\x12\x0c\n\ + peB\0\x12\x17\n\rcatalogue_str\x18\x05\x20\x03(\tB\0\"W\n\tCatalogue\x12\ + \x06\n\x02AD\x10\0\x12\x10\n\x0cSUBSCRIPTION\x10\x01\x12\x11\n\rCATALOGU\ + E_ALL\x10\x02\x12\x0b\n\x07SHUFFLE\x10\x03\x12\x0e\n\nCOMMERCIAL\x10\x04\ + \x1a\0\"\x17\n\x04Type\x12\r\n\tSTREAMING\x10\0\x1a\0:\0\"A\n\x0cAvailab\ + ility\x12\x17\n\rcatalogue_str\x18\x01\x20\x03(\tB\0\x12\x16\n\x05start\ + \x18\x02\x20\x01(\x0b2\x05.DateB\0:\0\"a\n\nSalePeriod\x12#\n\x0brestric\ + tion\x18\x01\x20\x03(\x0b2\x0c.RestrictionB\0\x12\x16\n\x05start\x18\x02\ + \x20\x01(\x0b2\x05.DateB\0\x12\x14\n\x03end\x18\x03\x20\x01(\x0b2\x05.Da\ + teB\0:\0\"+\n\nExternalId\x12\r\n\x03typ\x18\x01\x20\x01(\tB\0\x12\x0c\n\ \x02id\x18\x02\x20\x01(\tB\0:\0\"\xa2\x02\n\tAudioFile\x12\x11\n\x07file\ _id\x18\x01\x20\x01(\x0cB\0\x12#\n\x06format\x18\x02\x20\x01(\x0e2\x11.A\ udioFile.FormatB\0\"\xda\x01\n\x06Format\x12\x11\n\rOGG_VORBIS_96\x10\0\ @@ -9027,42 +9799,48 @@ static file_descriptor_proto_data: &'static [u8] = b"\ MP3_160\x10\x05\x12\n\n\x06MP3_96\x10\x06\x12\x0f\n\x0bMP3_160_ENC\x10\ \x07\x12\x10\n\x0cMP4_128_DUAL\x10\x08\x12\n\n\x06OTHER3\x10\t\x12\x0b\n\ \x07AAC_160\x10\n\x12\x0b\n\x07AAC_320\x10\x0b\x12\x0b\n\x07MP4_128\x10\ - \x0c\x12\n\n\x06OTHER5\x10\r\x1a\0:\0\"a\n\x0bPublishTime\x12\x0e\n\x04y\ - ear\x18\x01\x20\x01(\x11B\0\x12\x0f\n\x05month\x18\x02\x20\x01(\x11B\0\ - \x12\r\n\x03day\x18\x03\x20\x01(\x11B\0\x12\x10\n\x06minute\x18\x05\x20\ - \x01(\x11B\0\x12\x0e\n\x04hour\x18\x04\x20\x01(\x11B\0:\0\"\xc2\x03\n\ - \x04Show\x12\r\n\x03gid\x18\x01\x20\x01(\x0cB\0\x12\x0e\n\x04name\x18\ - \x02\x20\x01(\tB\0\x12\x1b\n\x07episode\x18F\x20\x03(\x0b2\x08.EpisodeB\ - \0\x12\x15\n\x0bdescription\x18@\x20\x01(\tB\0\x12\x13\n\tpublisher\x18B\ - \x20\x01(\tB\0\x12\x12\n\x08language\x18C\x20\x01(\tB\0\x12\x12\n\x08exp\ - licit\x18D\x20\x01(\x08B\0\x12\x1d\n\x06covers\x18E\x20\x01(\x0b2\x0b.Im\ - ageGroupB\0\x12#\n\x0brestriction\x18H\x20\x03(\x0b2\x0c.RestrictionB\0\ - \x12\x20\n\nmedia_type\x18J\x20\x01(\x0e2\n.MediaTypeB\0\x12.\n\x11consu\ - mption_order\x18K\x20\x01(\x0e2\x11.ConsumptionOrderB\0\x12+\n!interpret\ - _restriction_using_geoip\x18L\x20\x01(\x08B\0\x12\x1b\n\x11country_of_or\ - igin\x18O\x20\x01(\tB\0\x12\x1f\n\ncategories\x18P\x20\x03(\x0b2\t.Categ\ - oryB\0\x12'\n\x0bpassthrough\x18Q\x20\x01(\x0e2\x10.PassthroughEnumB\0:\ - \0\"\xfd\x03\n\x07Episode\x12\r\n\x03gid\x18\x01\x20\x01(\x0cB\0\x12\x0e\ - \n\x04name\x18\x02\x20\x01(\tB\0\x12\x12\n\x08duration\x18\x07\x20\x01(\ - \x11B\0\x12\x14\n\npopularity\x18\x08\x20\x01(\x11B\0\x12\x1a\n\x04file\ - \x18\x0c\x20\x03(\x0b2\n.AudioFileB\0\x12\x15\n\x0bdescription\x18@\x20\ - \x01(\tB\0\x12\x1d\n\x0cpublish_time\x18B\x20\x01(\x0b2\x05.DateB\0\x12\ - \x1d\n\x06covers\x18D\x20\x01(\x0b2\x0b.ImageGroupB\0\x12\x12\n\x08langu\ - age\x18E\x20\x01(\tB\0\x12\x12\n\x08explicit\x18F\x20\x01(\x08B\0\x12\ - \x15\n\x04show\x18G\x20\x01(\x0b2\x05.ShowB\0\x12\x1d\n\x07preview\x18J\ - \x20\x03(\x0b2\n.AudioFileB\0\x12#\n\x0brestriction\x18K\x20\x03(\x0b2\ - \x0c.RestrictionB\0\x12\x1f\n\x15suppress_monetization\x18N\x20\x01(\x08\ - B\0\x12#\n\x19allow_background_playback\x18O\x20\x01(\x08B\0\x12+\n!inte\ - rpret_restriction_using_geoip\x18Q\x20\x01(\x08B\0\x12\x16\n\x0cexternal\ - _url\x18S\x20\x01(\tB\0\x12(\n\x0eoriginal_audio\x18T\x20\x01(\x0b2\x0e.\ - OriginalAudioB\0:\0\"@\n\x08Category\x12\x0e\n\x04name\x18\x01\x20\x01(\ - \tB\0\x12\"\n\rsubcategories\x18\x02\x20\x03(\x0b2\t.CategoryB\0:\0\"!\n\ - \rOriginalAudio\x12\x0e\n\x04uuid\x18\x01\x20\x01(\x0cB\0:\0*>\n\x10Cons\ - umptionOrder\x12\x0e\n\nSEQUENTIAL\x10\x01\x12\x0c\n\x08EPISODIC\x10\x02\ - \x12\n\n\x06RECENT\x10\x03\x1a\0*.\n\tMediaType\x12\t\n\x05MIXED\x10\0\ - \x12\t\n\x05AUDIO\x10\x01\x12\t\n\x05VIDEO\x10\x02\x1a\0*7\n\x0fPassthro\ - ughEnum\x12\x0b\n\x07UNKNOWN\x10\0\x12\x08\n\x04NONE\x10\x01\x12\x0b\n\ - \x07ALLOWED\x10\x02\x1a\0B\0b\x06proto2\ + \x0c\x12\n\n\x06OTHER5\x10\r\x1a\0:\0\"\x20\n\tVideoFile\x12\x11\n\x07fi\ + le_id\x18\x01\x20\x01(\x0cB\0:\0\"\xf6\x05\n\x04Show\x12\r\n\x03gid\x18\ + \x01\x20\x01(\x0cB\0\x12\x0e\n\x04name\x18\x02\x20\x01(\tB\0\x12\x15\n\ + \x0bdescription\x18@\x20\x01(\tB\0\x12\x1f\n\x15deprecated_popularity\ + \x18A\x20\x01(\x11B\0\x12\x13\n\tpublisher\x18B\x20\x01(\tB\0\x12\x12\n\ + \x08language\x18C\x20\x01(\tB\0\x12\x12\n\x08explicit\x18D\x20\x01(\x08B\ + \0\x12\x1d\n\x06covers\x18E\x20\x01(\x0b2\x0b.ImageGroupB\0\x12\x1b\n\ + \x07episode\x18F\x20\x03(\x0b2\x08.EpisodeB\0\x12\x1f\n\tcopyright\x18G\ + \x20\x03(\x0b2\n.CopyrightB\0\x12#\n\x0brestriction\x18H\x20\x03(\x0b2\ + \x0c.RestrictionB\0\x12\x11\n\x07keyword\x18I\x20\x03(\tB\0\x12%\n\nmedi\ + a_type\x18J\x20\x01(\x0e2\x0f.Show.MediaTypeB\0\x123\n\x11consumption_or\ + der\x18K\x20\x01(\x0e2\x16.Show.ConsumptionOrderB\0\x12+\n!interpret_res\ + triction_using_geoip\x18L\x20\x01(\x08B\0\x12%\n\x0cavailability\x18N\ + \x20\x03(\x0b2\r.AvailabilityB\0\x12\x1b\n\x11country_of_origin\x18O\x20\ + \x01(\tB\0\x12\x1f\n\ncategories\x18P\x20\x03(\x0b2\t.CategoryB\0\x12,\n\ + \x0bpassthrough\x18Q\x20\x01(\x0e2\x15.Show.PassthroughEnumB\0\".\n\tMed\ + iaType\x12\t\n\x05MIXED\x10\0\x12\t\n\x05AUDIO\x10\x01\x12\t\n\x05VIDEO\ + \x10\x02\x1a\0\">\n\x10ConsumptionOrder\x12\x0e\n\nSEQUENTIAL\x10\x01\ + \x12\x0c\n\x08EPISODIC\x10\x02\x12\n\n\x06RECENT\x10\x03\x1a\0\"7\n\x0fP\ + assthroughEnum\x12\x0b\n\x07UNKNOWN\x10\0\x12\x08\n\x04NONE\x10\x01\x12\ + \x0b\n\x07ALLOWED\x10\x02\x1a\0:\0\"\xd7\x05\n\x07Episode\x12\r\n\x03gid\ + \x18\x01\x20\x01(\x0cB\0\x12\x0e\n\x04name\x18\x02\x20\x01(\tB\0\x12\x12\ + \n\x08duration\x18\x07\x20\x01(\x11B\0\x12\x14\n\npopularity\x18\x08\x20\ + \x01(\x11B\0\x12\x1a\n\x04file\x18\x0c\x20\x03(\x0b2\n.AudioFileB\0\x12\ + \x15\n\x0bdescription\x18@\x20\x01(\tB\0\x12\x10\n\x06number\x18A\x20\ + \x01(\x11B\0\x12\x1d\n\x0cpublish_time\x18B\x20\x01(\x0b2\x05.DateB\0\ + \x12\x1f\n\x15deprecated_popularity\x18C\x20\x01(\x11B\0\x12\x1d\n\x06co\ + vers\x18D\x20\x01(\x0b2\x0b.ImageGroupB\0\x12\x12\n\x08language\x18E\x20\ + \x01(\tB\0\x12\x12\n\x08explicit\x18F\x20\x01(\x08B\0\x12\x15\n\x04show\ + \x18G\x20\x01(\x0b2\x05.ShowB\0\x12\x1b\n\x05video\x18H\x20\x03(\x0b2\n.\ + VideoFileB\0\x12#\n\rvideo_preview\x18I\x20\x03(\x0b2\n.VideoFileB\0\x12\ + #\n\raudio_preview\x18J\x20\x03(\x0b2\n.AudioFileB\0\x12#\n\x0brestricti\ + on\x18K\x20\x03(\x0b2\x0c.RestrictionB\0\x12#\n\x0cfreeze_frame\x18L\x20\ + \x01(\x0b2\x0b.ImageGroupB\0\x12\x11\n\x07keyword\x18M\x20\x03(\tB\0\x12\ + \x1f\n\x15suppress_monetization\x18N\x20\x01(\x08B\0\x12+\n!interpret_re\ + striction_using_geoip\x18O\x20\x01(\x08B\0\x12#\n\x19allow_background_pl\ + ayback\x18Q\x20\x01(\x08B\0\x12%\n\x0cavailability\x18R\x20\x03(\x0b2\r.\ + AvailabilityB\0\x12\x16\n\x0cexternal_url\x18S\x20\x01(\tB\0\x12(\n\x0eo\ + riginal_audio\x18T\x20\x01(\x0b2\x0e.OriginalAudioB\0:\0\"@\n\x08Categor\ + y\x12\x0e\n\x04name\x18\x01\x20\x01(\tB\0\x12\"\n\rsubcategories\x18\x02\ + \x20\x03(\x0b2\t.CategoryB\0:\0\"!\n\rOriginalAudio\x12\x0e\n\x04uuid\ + \x18\x01\x20\x01(\x0cB\0:\0B\0b\x06proto2\ "; static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { From b96405af8262fc5b0e0567440f969d110492a836 Mon Sep 17 00:00:00 2001 From: ashthespy Date: Wed, 9 Oct 2019 19:49:13 +0200 Subject: [PATCH 5/8] Make `SpotifyId` understand more URI formats --- connect/src/spirc.rs | 44 +++++++++++++++++++++++++++--------------- core/src/spotify_id.rs | 13 ++++++++++--- metadata/src/lib.rs | 4 ++++ 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 92e26ce0..5e00ebb0 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -13,14 +13,14 @@ use context::StationContext; use librespot_core::config::ConnectConfig; use librespot_core::mercury::MercuryError; use librespot_core::session::Session; -use librespot_core::spotify_id::SpotifyId; +use librespot_core::spotify_id::{SpotifyId, SpotifyIdError}; use librespot_core::util::SeqGenerator; use librespot_core::version; use librespot_core::volume::Volume; use playback::mixer::Mixer; use playback::player::Player; use protocol; -use protocol::spirc::{DeviceState, Frame, MessageType, PlayStatus, State}; +use protocol::spirc::{DeviceState, Frame, MessageType, PlayStatus, State, TrackRef}; pub struct SpircTask { player: Player, @@ -797,7 +797,7 @@ impl SpircTask { } fn update_tracks(&mut self, frame: &protocol::spirc::Frame) { - // debug!("State: {:?}", frame.get_state()); + debug!("State: {:?}", frame.get_state()); let index = frame.get_state().get_playing_track_index(); let context_uri = frame.get_state().get_context_uri().to_owned(); let tracks = frame.get_state().get_track(); @@ -813,31 +813,43 @@ impl SpircTask { self.state.set_shuffle(frame.get_state().get_shuffle()); } + // should this be a method of SpotifyId directly? + fn get_spotify_id_for_track(&self, track_ref: &TrackRef) -> Result { + SpotifyId::from_raw(track_ref.get_gid()).or_else(|_| { + let uri = track_ref.get_uri(); + debug!("Malformed or no gid, attempting to parse URI <{}>", uri); + SpotifyId::from_uri(uri) + }) + } + fn load_track(&mut self, play: bool) { let context_uri = self.state.get_context_uri().to_owned(); - let index = self.state.get_playing_track_index(); - info!("context: {}", context_uri); - // Redundant check here - let track = if context_uri.contains(":show:") || context_uri.contains(":episode:") { - let uri = self.state.get_track()[index as usize].get_uri(); - SpotifyId::from_uri(uri).expect("Unable to parse uri") - } else { - let mut index = self.state.get_playing_track_index(); - // Check for malformed gid - let tracks_len = self.state.get_track().len() as u32; + let mut index = self.state.get_playing_track_index(); + let tracks_len = self.state.get_track().len() as u32; + debug!( + "Loading context: {} index: [{}] of {}", + context_uri, index, tracks_len + ); + // Tracks either have a gid or uri. + // Context based frames sometimes use spotify:meta:page: that needs to be ignored. + let track = { let mut track_ref = &self.state.get_track()[index as usize]; - while track_ref.get_gid().len() != 16 { + let mut track_id = self.get_spotify_id_for_track(track_ref); + while track_id.is_err() { warn!( "Skipping track {:?} at position [{}] of {}", track_ref.get_uri(), index, tracks_len ); + // This will keep looping over, instead we should cylce tracks only once index = if index + 1 < tracks_len { index + 1 } else { 0 }; track_ref = &self.state.get_track()[index as usize]; + track_id = self.get_spotify_id_for_track(track_ref); } - SpotifyId::from_raw(track_ref.get_gid()).unwrap() - }; + track_id + } + .unwrap(); let position = self.state.get_position_ms(); let end_of_track = self.player.load(track, play, position); diff --git a/core/src/spotify_id.rs b/core/src/spotify_id.rs index c8f01674..e6f0cdd8 100644 --- a/core/src/spotify_id.rs +++ b/core/src/spotify_id.rs @@ -5,6 +5,7 @@ use std::fmt; pub enum SpotifyAudioType { Track, Podcast, + NonPlayable, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -71,12 +72,18 @@ impl SpotifyId { pub fn from_uri(uri: &str) -> Result { let parts = uri.split(":").collect::>(); - if uri.contains(":show:") || uri.contains(":episode:") { - let mut spotify_id = SpotifyId::from_base62(parts[2]).unwrap(); + let gid = parts.last().unwrap(); + if uri.contains(":episode:") { + let mut spotify_id = SpotifyId::from_base62(gid).unwrap(); let _ = std::mem::replace(&mut spotify_id.audio_type, SpotifyAudioType::Podcast); Ok(spotify_id) + } else if uri.contains(":track:") { + SpotifyId::from_base62(gid) } else { - SpotifyId::from_base62(parts[2]) + // show/playlist/artist/album/?? + let mut spotify_id = SpotifyId::from_base62(gid).unwrap(); + let _ = std::mem::replace(&mut spotify_id.audio_type, SpotifyAudioType::NonPlayable); + Ok(spotify_id) } } diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 75a42e2f..344a3a54 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -8,6 +8,7 @@ extern crate librespot_protocol as protocol; pub mod cover; +use futures::future; use futures::Future; use linear_map::LinearMap; @@ -71,6 +72,9 @@ impl AudioItem { match id.audio_type { SpotifyAudioType::Track => Track::get_audio_item(session, id), SpotifyAudioType::Podcast => Episode::get_audio_item(session, id), + SpotifyAudioType::NonPlayable => { + Box::new(future::err::(MercuryError)) + } } } } From 508c7e2b260c041048373f12b33fca7702c4fe13 Mon Sep 17 00:00:00 2001 From: ashthespy Date: Tue, 22 Oct 2019 11:05:35 +0100 Subject: [PATCH 6/8] Tweak track loading --- connect/src/spirc.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 5e00ebb0..041bc88e 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -13,7 +13,7 @@ use context::StationContext; use librespot_core::config::ConnectConfig; use librespot_core::mercury::MercuryError; use librespot_core::session::Session; -use librespot_core::spotify_id::{SpotifyId, SpotifyIdError}; +use librespot_core::spotify_id::{SpotifyAudioType, SpotifyId, SpotifyIdError}; use librespot_core::util::SeqGenerator; use librespot_core::version; use librespot_core::volume::Volume; @@ -825,31 +825,38 @@ impl SpircTask { fn load_track(&mut self, play: bool) { let context_uri = self.state.get_context_uri().to_owned(); let mut index = self.state.get_playing_track_index(); + let start_index = index; let tracks_len = self.state.get_track().len() as u32; debug!( - "Loading context: {} index: [{}] of {}", + "Loading context: <{}> index: [{}] of {}", context_uri, index, tracks_len ); - // Tracks either have a gid or uri. - // Context based frames sometimes use spotify:meta:page: that needs to be ignored. + // Cycle through all tracks, break if we don't find any playable tracks + // TODO: This will panic if no playable tracks are found! + // tracks in each frame either have a gid or uri (that may or may not be a valid track) + // E.g - context based frames sometimes contain tracks with let track = { let mut track_ref = &self.state.get_track()[index as usize]; let mut track_id = self.get_spotify_id_for_track(track_ref); - while track_id.is_err() { + while track_id.is_err() || track_id.unwrap().audio_type == SpotifyAudioType::NonPlayable { warn!( - "Skipping track {:?} at position [{}] of {}", + "Skipping track <{:?}> at position [{}] of {}", track_ref.get_uri(), index, tracks_len ); - // This will keep looping over, instead we should cylce tracks only once index = if index + 1 < tracks_len { index + 1 } else { 0 }; + if index == start_index { + warn!("No playable track found in state: {:?}", self.state); + break; + } + self.state.set_playing_track_index(index); track_ref = &self.state.get_track()[index as usize]; track_id = self.get_spotify_id_for_track(track_ref); } track_id } - .unwrap(); + .expect("Invalid SpotifyId"); let position = self.state.get_position_ms(); let end_of_track = self.player.load(track, play, position); From ee3a756a6edf8748e90d500430f317c57587e819 Mon Sep 17 00:00:00 2001 From: ashthespy Date: Wed, 30 Oct 2019 13:53:11 +0100 Subject: [PATCH 7/8] Fix borrow for Rust 1.32.0 --- connect/src/spirc.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 041bc88e..299bae02 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -836,8 +836,8 @@ impl SpircTask { // tracks in each frame either have a gid or uri (that may or may not be a valid track) // E.g - context based frames sometimes contain tracks with let track = { - let mut track_ref = &self.state.get_track()[index as usize]; - let mut track_id = self.get_spotify_id_for_track(track_ref); + let mut track_ref = self.state.get_track()[index as usize].clone(); + let mut track_id = self.get_spotify_id_for_track(&track_ref); while track_id.is_err() || track_id.unwrap().audio_type == SpotifyAudioType::NonPlayable { warn!( "Skipping track <{:?}> at position [{}] of {}", @@ -846,13 +846,13 @@ impl SpircTask { tracks_len ); index = if index + 1 < tracks_len { index + 1 } else { 0 }; + self.state.set_playing_track_index(index); if index == start_index { warn!("No playable track found in state: {:?}", self.state); break; } - self.state.set_playing_track_index(index); - track_ref = &self.state.get_track()[index as usize]; - track_id = self.get_spotify_id_for_track(track_ref); + track_ref = self.state.get_track()[index as usize].clone(); + track_id = self.get_spotify_id_for_track(&track_ref); } track_id } From 939fc583e7e8221a457085f8e63918caa224778e Mon Sep 17 00:00:00 2001 From: ashthespy Date: Fri, 1 Nov 2019 17:01:58 +0100 Subject: [PATCH 8/8] Help `pkg-config` with explicit paths --- contrib/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/Dockerfile b/contrib/Dockerfile index 9cf2d134..74b83d31 100644 --- a/contrib/Dockerfile +++ b/contrib/Dockerfile @@ -44,6 +44,10 @@ RUN mkdir /build && \ ENV CARGO_TARGET_DIR /build ENV CARGO_HOME /build/cache ENV PKG_CONFIG_ALLOW_CROSS=1 +ENV PKG_CONFIG_PATH_aarch64-unknown-linux-gnu=/usr/lib/aarch64-linux-gnu/pkgconfig/ +ENV PKG_CONFIG_PATH_arm-unknown-linux-gnueabihf=/usr/lib/arm-linux-gnueabihf/pkgconfig/ +ENV PKG_CONFIG_PATH_arm-unknown-linux-gnueabi=/usr/lib/arm-linux-gnueabi/pkgconfig/ +ENV PKG_CONFIG_PATH_mipsel-unknown-linux-gnu=/usr/lib/mipsel-linux-gnu/pkgconfig/ ADD . /src WORKDIR /src