diff --git a/Cargo.lock b/Cargo.lock index 2693ccb8..c059eca2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -113,7 +113,7 @@ source = "git+https://github.com/stepancheg/rust-protobuf.git#d6e80593f38ce47dfa [[package]] name = "protobuf_macros" version = "0.1.0" -source = "git+https://github.com/plietar/rust-protobuf-macros.git#5fa976178a48b01bdf2da6d5e7929367e348ea04" +source = "git+https://github.com/plietar/rust-protobuf-macros.git#3b49de3937a34b7a21be1d13caea4348a93c6de4" [[package]] name = "rand" @@ -143,7 +143,7 @@ dependencies = [ [[package]] name = "rust-gmp" version = "0.2.0" -source = "git+https://github.com/plietar/rust-gmp.git#db2bb627165b12ebe18a41a941ac6284ce9b895d" +source = "git+https://github.com/plietar/rust-gmp.git#cc003c224559f6035cd34a7ed5c6284a49785816" dependencies = [ "num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -185,7 +185,7 @@ name = "vergen" version = "0.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/protocol/build.rs b/protocol/build.rs index c205efcc..2db7ff19 100644 --- a/protocol/build.rs +++ b/protocol/build.rs @@ -43,12 +43,7 @@ fn main() { &proto.join("authentication.proto"), &proto.join("mercury.proto"), &proto.join("metadata.proto"), - &proto.join("playlist4changes.proto"), - &proto.join("playlist4content.proto"), - &proto.join("playlist4issues.proto"), - &proto.join("playlist4meta.proto"), - &proto.join("playlist4ops.proto"), - &proto.join("playlist4service.proto"), + &proto.join("spirc.proto"), ]).unwrap(); } diff --git a/protocol/proto/ad-hermes-proxy.proto b/protocol/proto/ad-hermes-proxy.proto new file mode 100644 index 00000000..9fc50248 --- /dev/null +++ b/protocol/proto/ad-hermes-proxy.proto @@ -0,0 +1,49 @@ +message Rule { + optional string type = 0x1; + optional uint32 times = 0x2; + optional uint64 interval = 0x3; +} + +message AdRequest { + optional string client_language = 0x1; + optional string product = 0x2; + optional uint32 version = 0x3; + optional string type = 0x4; + repeated string avoidAds = 0x5; +} + +message AdQueueResponse { + repeated AdQueueEntry adQueueEntry = 0x1; +} + +message AdFile { + optional string id = 0x1; + optional string format = 0x2; +} + +message AdQueueEntry { + optional uint64 start_time = 0x1; + optional uint64 end_time = 0x2; + optional double priority = 0x3; + optional string token = 0x4; + optional uint32 ad_version = 0x5; + optional string id = 0x6; + optional string type = 0x7; + optional string campaign = 0x8; + optional string advertiser = 0x9; + optional string url = 0xa; + optional uint64 duration = 0xb; + optional uint64 expiry = 0xc; + optional string tracking_url = 0xd; + optional string banner_type = 0xe; + optional string html = 0xf; + optional string image = 0x10; + optional string background_image = 0x11; + optional string background_url = 0x12; + optional string background_color = 0x13; + optional string title = 0x14; + optional string caption = 0x15; + repeated AdFile file = 0x16; + repeated Rule rule = 0x17; +} + diff --git a/protocol/proto/appstore.proto b/protocol/proto/appstore.proto new file mode 100644 index 00000000..d526cf02 --- /dev/null +++ b/protocol/proto/appstore.proto @@ -0,0 +1,93 @@ +message AppInfo { + optional string identifier = 0x1; + optional int32 version_int = 0x2; +} + +message AppInfoList { + repeated AppInfo items = 0x1; +} + +message SemanticVersion { + optional int32 major = 0x1; + optional int32 minor = 0x2; + optional int32 patch = 0x3; +} + +message RequestHeader { + optional string market = 0x1; + optional Platform platform = 0x2; + enum Platform { + WIN32_X86 = 0x0; + OSX_X86 = 0x1; + LINUX_X86 = 0x2; + IPHONE_ARM = 0x3; + SYMBIANS60_ARM = 0x4; + OSX_POWERPC = 0x5; + ANDROID_ARM = 0x6; + WINCE_ARM = 0x7; + LINUX_X86_64 = 0x8; + OSX_X86_64 = 0x9; + PALM_ARM = 0xa; + LINUX_SH = 0xb; + FREEBSD_X86 = 0xc; + FREEBSD_X86_64 = 0xd; + BLACKBERRY_ARM = 0xe; + SONOS_UNKNOWN = 0xf; + LINUX_MIPS = 0x10; + LINUX_ARM = 0x11; + LOGITECH_ARM = 0x12; + LINUX_BLACKFIN = 0x13; + ONKYO_ARM = 0x15; + QNXNTO_ARM = 0x16; + BADPLATFORM = 0xff; + } + optional AppInfoList app_infos = 0x6; + optional string bridge_identifier = 0x7; + optional SemanticVersion bridge_version = 0x8; + optional DeviceClass device_class = 0x9; + enum DeviceClass { + DESKTOP = 0x1; + TABLET = 0x2; + MOBILE = 0x3; + WEB = 0x4; + TV = 0x5; + } +} + +message AppItem { + optional string identifier = 0x1; + optional Requirement requirement = 0x2; + enum Requirement { + REQUIRED_INSTALL = 0x1; + LAZYLOAD = 0x2; + OPTIONAL_INSTALL = 0x3; + } + optional string manifest = 0x4; + optional string checksum = 0x5; + optional string bundle_uri = 0x6; + optional string small_icon_uri = 0x7; + optional string large_icon_uri = 0x8; + optional string medium_icon_uri = 0x9; + optional Type bundle_type = 0xa; + enum Type { + APPLICATION = 0x0; + FRAMEWORK = 0x1; + BRIDGE = 0x2; + } + optional SemanticVersion version = 0xb; + optional uint32 ttl_in_seconds = 0xc; + optional IdentifierList categories = 0xd; +} + +message AppList { + repeated AppItem items = 0x1; +} + +message IdentifierList { + repeated string identifiers = 0x1; +} + +message BannerConfig { + optional string json = 0x1; +} + diff --git a/protocol/proto/authentication.proto b/protocol/proto/authentication.proto index dedf63b6..30e4f6b6 100644 --- a/protocol/proto/authentication.proto +++ b/protocol/proto/authentication.proto @@ -1,21 +1,20 @@ -// size=30 + message ClientResponseEncrypted { - required LoginCredentials login_credentials = 0xa; // idx=0 offset=c - optional AccountCreation account_creation = 0x14; // idx=1 offset=10 - optional FingerprintResponseUnion fingerprint_response = 0x1e; // idx=2 offset=14 - optional PeerTicketUnion peer_ticket = 0x28; // idx=3 offset=18 - required SystemInfo system_info = 0x32; // idx=4 offset=1c - optional string platform_model = 0x3c; // idx=5 offset=20 - optional string version_string = 0x46; // idx=6 offset=24 - optional LibspotifyAppKey appkey = 0x50; // idx=7 offset=28 - optional ClientInfo client_info = 0x5a; // idx=8 offset=2c + required LoginCredentials login_credentials = 0xa; + optional AccountCreation account_creation = 0x14; + optional FingerprintResponseUnion fingerprint_response = 0x1e; + optional PeerTicketUnion peer_ticket = 0x28; + required SystemInfo system_info = 0x32; + optional string platform_model = 0x3c; + optional string version_string = 0x46; + optional LibspotifyAppKey appkey = 0x50; + optional ClientInfo client_info = 0x5a; } -// size=18 message LoginCredentials { - optional string username = 0xa; // idx=0 offset=c - required Type typ = 0x14; // idx=1 offset=10 - optional bytes auth_data = 0x1e; // idx=2 offset=14 + optional string username = 0xa; + required Type typ = 0x14; + optional bytes auth_data = 0x1e; } enum Type { @@ -31,51 +30,44 @@ enum AccountCreation { ACCOUNT_CREATION_ALWAYS_CREATE = 0x3; } -// size=14 message FingerprintResponseUnion { - optional FingerprintGrainResponse grain = 0xa; // idx=0 offset=c - optional FingerprintHmacRipemdResponse hmac_ripemd = 0x14; // idx=1 offset=10 + optional FingerprintGrainResponse grain = 0xa; + optional FingerprintHmacRipemdResponse hmac_ripemd = 0x14; } -// size=1c message FingerprintGrainResponse { - required bytes encrypted_key = 0xa; // idx=0 offset=c size=f + required bytes encrypted_key = 0xa; } -// size=20 message FingerprintHmacRipemdResponse { - required bytes hmac = 0xa; // idx=0 offset=c size=13 + required bytes hmac = 0xa; } -// size=14 message PeerTicketUnion { - optional PeerTicketPublicKey public_key = 0xa; // idx=0 offset=c - optional PeerTicketOld old_ticket = 0x14; // idx=1 offset=10 + optional PeerTicketPublicKey public_key = 0xa; + optional PeerTicketOld old_ticket = 0x14; } -// size=8c message PeerTicketPublicKey { - required bytes public_key = 0xa; // idx=0 offset=c size=7f + required bytes public_key = 0xa; } -// size=90 message PeerTicketOld { - required bytes peer_ticket = 0xa; // idx=0 offset=c - required bytes peer_ticket_signature = 0x14; // idx=1 offset=10 size=7f + required bytes peer_ticket = 0xa; + required bytes peer_ticket_signature = 0x14; } -// size=34 message SystemInfo { - required CpuFamily cpu_family = 0xa; // idx=0 offset=c - optional uint32 cpu_subtype = 0x14; // idx=1 offset=10 - optional uint32 cpu_ext = 0x1e; // idx=2 offset=14 - optional Brand brand = 0x28; // idx=3 offset=18 - optional uint32 brand_flags = 0x32; // idx=4 offset=1c - required Os os = 0x3c; // idx=5 offset=20 - optional uint32 os_version = 0x46; // idx=6 offset=24 - optional uint32 os_ext = 0x50; // idx=7 offset=28 - optional string system_information_string = 0x5a; // idx=8 offset=2c - optional string device_id = 0x64; // idx=9 offset=30 + required CpuFamily cpu_family = 0xa; + optional uint32 cpu_subtype = 0x14; + optional uint32 cpu_ext = 0x1e; + optional Brand brand = 0x28; + optional uint32 brand_flags = 0x32; + required Os os = 0x3c; + optional uint32 os_version = 0x46; + optional uint32 os_ext = 0x50; + optional string system_information_string = 0x5a; + optional string device_id = 0x64; } enum CpuFamily { @@ -124,25 +116,22 @@ enum Os { OS_BCO = 0x16; } -// size=168 message LibspotifyAppKey { - required uint32 version = 0x1; // idx=0 offset=c - required bytes devkey = 0x2; // idx=1 offset=10 size=7f - required bytes signature = 0x3; // idx=2 offset=90 size=bf - required string useragent = 0x4; // idx=3 offset=150 - required bytes callback_hash = 0x5; // idx=4 offset=154 size=13 + required uint32 version = 0x1; + required bytes devkey = 0x2; + required bytes signature = 0x3; + required string useragent = 0x4; + required bytes callback_hash = 0x5; } -// size=18 message ClientInfo { - optional bool limited = 0x1; // idx=0 offset=c - optional ClientInfoFacebook fb = 0x2; // idx=1 offset=10 - optional string language = 0x3; // idx=2 offset=14 + optional bool limited = 0x1; + optional ClientInfoFacebook fb = 0x2; + optional string language = 0x3; } -// size=10 message ClientInfoFacebook { - optional string machine_id = 0x1; // idx=0 offset=c + optional string machine_id = 0x1; } message AuthSuccess { diff --git a/protocol/proto/facebook-publish.proto b/protocol/proto/facebook-publish.proto new file mode 100644 index 00000000..31af8c50 --- /dev/null +++ b/protocol/proto/facebook-publish.proto @@ -0,0 +1,49 @@ +message EventReply { + optional int32 queued = 0x1; + optional RetryInfo retry = 0x2; +} + +message RetryInfo { + optional int32 retry_delay = 0x1; + optional int32 max_retry = 0x2; +} + +message Id { + optional string uri = 0x1; + optional int64 start_time = 0x2; +} + +message Start { + optional int32 length = 0x1; + optional string context_uri = 0x2; + optional int64 end_time = 0x3; +} + +message Seek { + optional int64 end_time = 0x1; +} + +message Pause { + optional int32 seconds_played = 0x1; + optional int64 end_time = 0x2; +} + +message Resume { + optional int32 seconds_played = 0x1; + optional int64 end_time = 0x2; +} + +message End { + optional int32 seconds_played = 0x1; + optional int64 end_time = 0x2; +} + +message Event { + optional Id id = 0x1; + optional Start start = 0x2; + optional Seek seek = 0x3; + optional Pause pause = 0x4; + optional Resume resume = 0x5; + optional End end = 0x6; +} + diff --git a/protocol/proto/facebook.proto b/protocol/proto/facebook.proto new file mode 100644 index 00000000..a0439a3a --- /dev/null +++ b/protocol/proto/facebook.proto @@ -0,0 +1,181 @@ +message Credential { + optional string facebook_uid = 0x1; + optional string access_token = 0x2; +} + +message EnableRequest { + optional Credential credential = 0x1; +} + +message EnableReply { + optional Credential credential = 0x1; +} + +message DisableRequest { + optional Credential credential = 0x1; +} + +message RevokeRequest { + optional Credential credential = 0x1; +} + +message InspectCredentialRequest { + optional Credential credential = 0x1; +} + +message InspectCredentialReply { + optional Credential alternative_credential = 0x1; + optional bool app_user = 0x2; + optional bool permanent_error = 0x3; + optional bool transient_error = 0x4; +} + +message UserState { + optional Credential credential = 0x1; +} + +message UpdateUserStateRequest { + optional Credential credential = 0x1; +} + +message OpenGraphError { + repeated string permanent = 0x1; + repeated string invalid_token = 0x2; + repeated string retries = 0x3; +} + +message OpenGraphScrobble { + optional int32 create_delay = 0x1; +} + +message OpenGraphConfig { + optional OpenGraphError error = 0x1; + optional OpenGraphScrobble scrobble = 0x2; +} + +message AuthConfig { + optional string url = 0x1; + repeated string permissions = 0x2; + repeated string blacklist = 0x3; + repeated string whitelist = 0x4; + repeated string cancel = 0x5; +} + +message ConfigReply { + optional string domain = 0x1; + optional string app_id = 0x2; + optional string app_namespace = 0x3; + optional AuthConfig auth = 0x4; + optional OpenGraphConfig og = 0x5; +} + +message UserFields { + optional bool app_user = 0x1; + optional bool display_name = 0x2; + optional bool first_name = 0x3; + optional bool middle_name = 0x4; + optional bool last_name = 0x5; + optional bool picture_large = 0x6; + optional bool picture_square = 0x7; + optional bool gender = 0x8; + optional bool email = 0x9; +} + +message UserOptions { + optional bool cache_is_king = 0x1; +} + +message UserRequest { + optional UserOptions options = 0x1; + optional UserFields fields = 0x2; +} + +message User { + optional string spotify_username = 0x1; + optional string facebook_uid = 0x2; + optional bool app_user = 0x3; + optional string display_name = 0x4; + optional string first_name = 0x5; + optional string middle_name = 0x6; + optional string last_name = 0x7; + optional string picture_large = 0x8; + optional string picture_square = 0x9; + optional string gender = 0xa; + optional string email = 0xb; +} + +message FriendsFields { + optional bool app_user = 0x1; + optional bool display_name = 0x2; + optional bool picture_large = 0x6; +} + +message FriendsOptions { + optional int32 limit = 0x1; + optional int32 offset = 0x2; + optional bool cache_is_king = 0x3; + optional bool app_friends = 0x4; + optional bool non_app_friends = 0x5; +} + +message FriendsRequest { + optional FriendsOptions options = 0x1; + optional FriendsFields fields = 0x2; +} + +message FriendsReply { + repeated User friends = 0x1; + optional bool more = 0x2; +} + +message ShareRequest { + optional Credential credential = 0x1; + optional string uri = 0x2; + optional string message_text = 0x3; +} + +message ShareReply { + optional string post_id = 0x1; +} + +message InboxRequest { + optional Credential credential = 0x1; + repeated string facebook_uids = 0x3; + optional string message_text = 0x4; + optional string message_link = 0x5; +} + +message InboxReply { + optional string message_id = 0x1; + optional string thread_id = 0x2; +} + +message PermissionsOptions { + optional bool cache_is_king = 0x1; +} + +message PermissionsRequest { + optional Credential credential = 0x1; + optional PermissionsOptions options = 0x2; +} + +message PermissionsReply { + repeated string permissions = 0x1; +} + +message GrantPermissionsRequest { + optional Credential credential = 0x1; + repeated string permissions = 0x2; +} + +message GrantPermissionsReply { + repeated string granted = 0x1; + repeated string failed = 0x2; +} + +message TransferRequest { + optional Credential credential = 0x1; + optional string source_username = 0x2; + optional string target_username = 0x3; +} + diff --git a/protocol/proto/mercury.proto b/protocol/proto/mercury.proto index b7eb9eb4..c080bd10 100644 --- a/protocol/proto/mercury.proto +++ b/protocol/proto/mercury.proto @@ -1,49 +1,44 @@ -message MercuryRequest { - required string url = 0x01; - optional string mime = 0x02; - required string method = 0x03; -} - -message MercuryReply { - required string url = 0x01; - required string mime = 0x02; - required sint32 code = 0x04; - repeated Header header = 0x06; - - message Header { - required string key = 0x01; - required bytes value = 0x02; - } -} - -message MercuryGetRequest { - required string url = 0x01; - optional string method = 0x03; -} - message MercuryMultiGetRequest { - repeated MercuryGetRequest request = 0x01; -} - -message MercuryGetReply { - enum CachePolicy { - CACHE_NO = 1; - CACHE_PRIVATE = 2; - CACHE_PUBLIC = 3; - } - optional sint32 code = 0x01; - optional CachePolicy cache_policy = 0x03; - optional uint32 ttl = 0x04; - optional bytes etag = 0x05; - optional string mime = 0x06; - optional bytes body = 0x07; + repeated MercuryRequest request = 0x1; } message MercuryMultiGetReply { - repeated MercuryGetReply reply = 0x1; + repeated MercuryReply reply = 0x1; } -message MercurySubscribed { - required string url = 0x1; +message MercuryRequest { + optional string uri = 0x1; + optional string content_type = 0x2; + optional bytes body = 0x3; + optional bytes etag = 0x4; +} + +message MercuryReply { + optional sint32 status_code = 0x1; + optional string status_message = 0x2; + optional CachePolicy cache_policy = 0x3; + enum CachePolicy { + CACHE_NO = 0x1; + CACHE_PRIVATE = 0x2; + CACHE_PUBLIC = 0x3; + } + optional sint32 ttl = 0x4; + optional bytes etag = 0x5; + optional string content_type = 0x6; + optional bytes body = 0x7; +} + + +message Header { + optional string uri = 0x01; + optional string content_type = 0x02; + optional string method = 0x03; + optional sint32 status_code = 0x04; + repeated UserField user_fields = 0x06; +} + +message UserField { + optional string key = 0x01; + optional bytes value = 0x02; } diff --git a/protocol/proto/mergedprofile.proto b/protocol/proto/mergedprofile.proto new file mode 100644 index 00000000..20f7dd5f --- /dev/null +++ b/protocol/proto/mergedprofile.proto @@ -0,0 +1,8 @@ +message MergedProfileRequest { +} + +message MergedProfileReply { + optional string username = 0x1; + optional string artistid = 0x2; +} + diff --git a/protocol/proto/metadata.proto b/protocol/proto/metadata.proto index 16ff07c3..2f5d2166 100644 --- a/protocol/proto/metadata.proto +++ b/protocol/proto/metadata.proto @@ -1,154 +1,159 @@ message TopTracks { - optional string country = 1; - repeated Track track = 2; + optional string country = 0x1; + repeated Track track = 0x2; } + message ActivityPeriod { - optional sint32 start_year = 1; - optional sint32 end_year = 2; - optional sint32 decade = 3; + optional sint32 start_year = 0x1; + optional sint32 end_year = 0x2; + optional sint32 decade = 0x3; } + message Artist { - optional bytes gid = 1; - optional string name = 2; - optional sint32 popularity = 3; - repeated TopTracks top_track = 4; - repeated AlbumGroup album_group = 5; - repeated AlbumGroup single_group = 6; - repeated AlbumGroup compilation_group = 7; - repeated AlbumGroup appears_on_group = 8; - repeated string genre = 9; - repeated ExternalId external_id = 10; - repeated Image portrait = 11; - repeated Biography biography = 12; - repeated ActivityPeriod activity_period = 13; - repeated Restriction restriction = 14; - repeated Artist related = 15; - optional bool is_portrait_album_cover = 16; - optional ImageGroup portrait_group = 17; + optional bytes gid = 0x1; + optional string name = 0x2; + optional sint32 popularity = 0x3; + repeated TopTracks top_track = 0x4; + repeated AlbumGroup album_group = 0x5; + repeated AlbumGroup single_group = 0x6; + repeated AlbumGroup compilation_group = 0x7; + repeated AlbumGroup appears_on_group = 0x8; + repeated string genre = 0x9; + repeated ExternalId external_id = 0xa; + repeated Image portrait = 0xb; + repeated Biography biography = 0xc; + repeated ActivityPeriod activity_period = 0xd; + repeated Restriction restriction = 0xe; + repeated Artist related = 0xf; + optional bool is_portrait_album_cover = 0x10; + optional ImageGroup portrait_group = 0x11; } + message AlbumGroup { - repeated Album album = 1; + repeated Album album = 0x1; } + message Date { - optional sint32 year = 1; - optional sint32 month = 2; - optional sint32 day = 3; + optional sint32 year = 0x1; + optional sint32 month = 0x2; + optional sint32 day = 0x3; } + message Album { + optional bytes gid = 0x1; + optional string name = 0x2; + repeated Artist artist = 0x3; + optional Type type = 0x4; enum Type { - ALBUM = 1; - SINGLE = 2; - COMPILATION = 3; + ALBUM = 0x1; + SINGLE = 0x2; + COMPILATION = 0x3; } - optional bytes gid = 1; - optional string name = 2; - repeated Artist artist = 3; - optional Type typ = 4; - optional string label = 5; - optional Date date = 6; - optional sint32 popularity = 7; - repeated string genre = 8; - repeated Image cover = 9; - repeated ExternalId external_id = 10; - repeated Disc disc = 11; - repeated string review = 12; - repeated Copyright copyright = 13; - repeated Restriction restriction = 14; - repeated Album related = 15; - repeated SalePeriod sale_period = 16; - optional ImageGroup cover_group = 17; + optional string label = 0x5; + optional Date date = 0x6; + optional sint32 popularity = 0x7; + repeated string genre = 0x8; + repeated Image cover = 0x9; + repeated ExternalId external_id = 0xa; + repeated Disc disc = 0xb; + repeated string review = 0xc; + repeated Copyright copyright = 0xd; + repeated Restriction restriction = 0xe; + repeated Album related = 0xf; + repeated SalePeriod sale_period = 0x10; + optional ImageGroup cover_group = 0x11; } message Track { - optional bytes gid = 1; - optional string name = 2; - optional Album album = 3; - repeated Artist artist = 4; - optional sint32 number = 5; - optional sint32 disc_number = 6; - optional sint32 duration = 7; - optional sint32 popularity = 8; - optional bool explicit = 9; - repeated ExternalId external_id = 10; - repeated Restriction restriction = 11; - repeated AudioFile file = 12; - repeated Track alternative = 13; - repeated SalePeriod sale_period = 14; - repeated AudioFile preview = 15; + optional bytes gid = 0x1; + optional string name = 0x2; + optional Album album = 0x3; + repeated Artist artist = 0x4; + optional sint32 number = 0x5; + optional sint32 disc_number = 0x6; + optional sint32 duration = 0x7; + optional sint32 popularity = 0x8; + optional bool explicit = 0x9; + repeated ExternalId external_id = 0xa; + repeated Restriction restriction = 0xb; + repeated AudioFile file = 0xc; + repeated Track alternative = 0xd; + repeated SalePeriod sale_period = 0xe; + repeated AudioFile preview = 0xf; } + message Image { + optional bytes file_id = 0x1; + optional Size size = 0x2; enum Size { - DEFAULT = 0; - SMALL = 1; - LARGE = 2; - XLARGE = 3; + DEFAULT = 0x0; + SMALL = 0x1; + LARGE = 0x2; + XLARGE = 0x3; } - optional bytes file_id = 1; - optional Size size = 2; - optional sint32 width = 3; - optional sint32 height = 4; + optional sint32 width = 0x3; + optional sint32 height = 0x4; } + message ImageGroup { - repeated Image image = 1; + repeated Image image = 0x1; } + message Biography { - optional string text = 1; - repeated Image portrait = 2; - repeated ImageGroup portrait_group = 3; + optional string text = 0x1; + repeated Image portrait = 0x2; + repeated ImageGroup portrait_group = 0x3; } + message Disc { - optional sint32 number = 1; - optional string name = 2; - repeated Track track = 3; + optional sint32 number = 0x1; + optional string name = 0x2; + repeated Track track = 0x3; } + message Copyright { + optional Type type = 0x1; enum Type { - P = 0; - C = 1; + P = 0x0; + C = 0x1; } - optional Type typ = 1; - optional string text = 2; + optional string text = 0x2; } + message Restriction { - enum Catalogue { - FREE = 0; - PREMIUM = 1; - SHUFFLE = 3; - COMMERCIAL = 4; - } + optional string countries_allowed = 0x2; + optional string countries_forbidden = 0x3; + optional Type type = 0x4; enum Type { - STREAMING = 0; + STREAMING = 0x0; } - repeated Catalogue catalogue = 1; - optional string countries_allowed = 2; - optional string countries_forbidden = 3; - optional Type typ = 4; - repeated string usage = 5; + repeated string catalogue_str = 0x5; } message SalePeriod { - repeated Restriction restriction = 1; - optional Date start = 2; - optional Date end = 3; + repeated Restriction restriction = 0x1; + optional Date start = 0x2; + optional Date end = 0x3; } message ExternalId { - optional string typ = 1; - optional string id = 2; + optional string type = 0x1; + optional string id = 0x2; } message AudioFile { + optional bytes file_id = 0x1; + optional Format format = 0x2; enum Format { - OGG_VORBIS_96 = 0; - OGG_VORBIS_160 = 1; - OGG_VORBIS_320 = 2; - MP3_256 = 3; - MP3_320 = 4; - MP3_160 = 5; - MP3_96 = 6; - OTHER1 = 7; // TODO - OTHER2 = 8; // TODO + OGG_VORBIS_96 = 0x0; + OGG_VORBIS_160 = 0x1; + OGG_VORBIS_320 = 0x2; + MP3_256 = 0x3; + MP3_320 = 0x4; + MP3_160 = 0x5; + MP3_96 = 0x6; + OTHER = 0x7; + OTHER2 = 0x8; } - optional bytes gid = 1; - optional Format format = 2; } + diff --git a/protocol/proto/playlist4changes.proto b/protocol/proto/playlist4changes.proto index c9764bfe..145ee59c 100644 --- a/protocol/proto/playlist4changes.proto +++ b/protocol/proto/playlist4changes.proto @@ -1,80 +1,84 @@ +import "playlist4ops.proto"; +import "playlist4meta.proto"; import "playlist4content.proto"; import "playlist4issues.proto"; -import "playlist4meta.proto"; -import "playlist4ops.proto"; message ChangeInfo { - optional string user = 1; - optional int32 timestamp = 2; - optional bool admin = 3; - optional bool undo = 4; - optional bool redo = 5; - optional bool merge = 6; - optional bool compressed = 7; - optional bool migration = 8; + optional string user = 0x1; + optional int32 timestamp = 0x2; + optional bool admin = 0x3; + optional bool undo = 0x4; + optional bool redo = 0x5; + optional bool merge = 0x6; + optional bool compressed = 0x7; + optional bool migration = 0x8; } + message Delta { - optional bytes base_version = 1; - repeated Op ops = 2; - optional ChangeInfo info = 4; + optional bytes base_version = 0x1; + repeated Op ops = 0x2; + optional ChangeInfo info = 0x4; } + message Merge { - optional bytes base_version = 1; - optional bytes merge_version = 2; - optional ChangeInfo info = 4; + optional bytes base_version = 0x1; + optional bytes merge_version = 0x2; + optional ChangeInfo info = 0x4; } + message ChangeSet { - enum Kind { - KIND_UNKNOWN = 0; - DELTA = 2; - MERGE = 3; - }; - required Kind kind = 1; - optional Delta delta = 2; - optional Merge merge = 3; + optional Kind kind = 0x1; + enum Kind { + KIND_UNKNOWN = 0x0; + DELTA = 0x2; + MERGE = 0x3; + } + optional Delta delta = 0x2; + optional Merge merge = 0x3; } + message RevisionTaggedChangeSet { - required bytes revision = 1; - required ChangeSet change_set = 2; + optional bytes revision = 0x1; + optional ChangeSet change_set = 0x2; } + message Diff { - required bytes from_revision = 1; - repeated Op ops = 2; - required bytes to_revision = 3; + optional bytes from_revision = 0x1; + repeated Op ops = 0x2; + optional bytes to_revision = 0x3; } + message ListDump { - optional bytes latestRevision = 1; - optional int32 length = 2; - optional ListAttributes attributes = 3; - optional ListChecksum checksum = 4; - optional ListItems contents = 5; - repeated Delta pendingDeltas = 7; + optional bytes latestRevision = 0x1; + optional int32 length = 0x2; + optional ListAttributes attributes = 0x3; + optional ListChecksum checksum = 0x4; + optional ListItems contents = 0x5; + repeated Delta pendingDeltas = 0x7; } + message ListChanges { - optional bytes baseRevision = 1; - repeated Delta deltas = 2; - optional bool wantResultingRevisions = 3; - optional bool wantSyncResult = 4; - optional ListDump dump = 5; - repeated int32 nonces = 6; + optional bytes baseRevision = 0x1; + repeated Delta deltas = 0x2; + optional bool wantResultingRevisions = 0x3; + optional bool wantSyncResult = 0x4; + optional ListDump dump = 0x5; + repeated int32 nonces = 0x6; } + message SelectedListContent { - optional bytes revision = 1; - optional int32 length = 2; - optional ListAttributes attributes = 3; - optional ListChecksum checksum = 4; - optional ListItems contents = 5; - optional Diff diff = 6; - - optional Diff syncResult = 7; - repeated bytes resultingRevisions = 8; - - optional bool multipleHeads = 9; - - optional bool upToDate = 10; - - repeated ClientResolveAction resolveAction = 12; - repeated ClientIssue issues = 13; - - repeated int32 nonces = 14; + optional bytes revision = 0x1; + optional int32 length = 0x2; + optional ListAttributes attributes = 0x3; + optional ListChecksum checksum = 0x4; + optional ListItems contents = 0x5; + optional Diff diff = 0x6; + optional Diff syncResult = 0x7; + repeated bytes resultingRevisions = 0x8; + optional bool multipleHeads = 0x9; + optional bool upToDate = 0xa; + repeated ClientResolveAction resolveAction = 0xc; + repeated ClientIssue issues = 0xd; + repeated int32 nonces = 0xe; } + diff --git a/protocol/proto/playlist4content.proto b/protocol/proto/playlist4content.proto index e5d7bc47..c6db8edf 100644 --- a/protocol/proto/playlist4content.proto +++ b/protocol/proto/playlist4content.proto @@ -2,30 +2,34 @@ import "playlist4meta.proto"; import "playlist4issues.proto"; message Item { - required string uri = 1; - optional ItemAttributes attributes = 2; + optional string uri = 0x1; + optional ItemAttributes attributes = 0x2; } + message ListItems { - required int32 pos = 1; - required bool truncated = 2; - repeated Item items = 3; + optional int32 pos = 0x1; + optional bool truncated = 0x2; + repeated Item items = 0x3; } + message ContentRange { - required int32 pos = 1; - optional int32 length = 2; + optional int32 pos = 0x1; + optional int32 length = 0x2; } + message ListContentSelection { - optional bool wantRevision = 1; - optional bool wantLength = 2; - optional bool wantAttributes = 3; - optional bool wantChecksum = 4; - optional bool wantContent = 5; - optional ContentRange contentRange = 6; - optional bool wantDiff = 7; - optional bytes baseRevision = 8; - optional bytes hintRevision = 9; - optional bool wantNothingIfUpToDate = 10; - optional bool wantResolveAction = 12; - repeated ClientIssue issues = 13; - repeated ClientResolveAction resolveAction = 14; + optional bool wantRevision = 0x1; + optional bool wantLength = 0x2; + optional bool wantAttributes = 0x3; + optional bool wantChecksum = 0x4; + optional bool wantContent = 0x5; + optional ContentRange contentRange = 0x6; + optional bool wantDiff = 0x7; + optional bytes baseRevision = 0x8; + optional bytes hintRevision = 0x9; + optional bool wantNothingIfUpToDate = 0xa; + optional bool wantResolveAction = 0xc; + repeated ClientIssue issues = 0xd; + repeated ClientResolveAction resolveAction = 0xe; } + diff --git a/protocol/proto/playlist4issues.proto b/protocol/proto/playlist4issues.proto index 2fa21993..6f5c26bb 100644 --- a/protocol/proto/playlist4issues.proto +++ b/protocol/proto/playlist4issues.proto @@ -1,40 +1,41 @@ message ClientIssue { - enum Level { - LEVEL_UNKNOWN = 0; - LEVEL_DEBUG = 1; - LEVEL_INFO = 2; - LEVEL_NOTICE = 3; - LEVEL_WARNING = 4; - LEVEL_ERROR = 5; - } - enum Code { - CODE_UNKNOWN = 0; - CODE_INDEX_OUT_OF_BOUNDS = 1; - CODE_VERSION_MISMATCH = 2; - CODE_CACHED_CHANGE = 3; - CODE_OFFLINE_CHANGE = 4; - CODE_CONCURRENT_CHANGE = 5; - } - optional Level level = 1; - optional Code code = 2; - optional int32 repeatCount = 3; + optional Level level = 0x1; + enum Level { + LEVEL_UNKNOWN = 0x0; + LEVEL_DEBUG = 0x1; + LEVEL_INFO = 0x2; + LEVEL_NOTICE = 0x3; + LEVEL_WARNING = 0x4; + LEVEL_ERROR = 0x5; + } + optional Code code = 0x2; + enum Code { + CODE_UNKNOWN = 0x0; + CODE_INDEX_OUT_OF_BOUNDS = 0x1; + CODE_VERSION_MISMATCH = 0x2; + CODE_CACHED_CHANGE = 0x3; + CODE_OFFLINE_CHANGE = 0x4; + CODE_CONCURRENT_CHANGE = 0x5; + } + optional int32 repeatCount = 0x3; } message ClientResolveAction { - enum Code { - CODE_UNKNOWN = 0; - CODE_NO_ACTION = 1; - CODE_RETRY = 2; - CODE_RELOAD = 3; - CODE_DISCARD_LOCAL_CHANGES = 4; - CODE_SEND_DUMP = 5; - CODE_DISPLAY_ERROR_MESSAGE = 6; - } - enum Initiator { - INITIATOR_UNKNOWN = 0; - INITIATOR_SERVER = 1; - INITIATOR_CLIENT = 2; - } - optional Code code = 1; - optional Initiator initiator = 2; + optional Code code = 0x1; + enum Code { + CODE_UNKNOWN = 0x0; + CODE_NO_ACTION = 0x1; + CODE_RETRY = 0x2; + CODE_RELOAD = 0x3; + CODE_DISCARD_LOCAL_CHANGES = 0x4; + CODE_SEND_DUMP = 0x5; + CODE_DISPLAY_ERROR_MESSAGE = 0x6; + } + optional Initiator initiator = 0x2; + enum Initiator { + INITIATOR_UNKNOWN = 0x0; + INITIATOR_SERVER = 0x1; + INITIATOR_CLIENT = 0x2; + } } + diff --git a/protocol/proto/playlist4meta.proto b/protocol/proto/playlist4meta.proto index d6013b37..1acaef7c 100644 --- a/protocol/proto/playlist4meta.proto +++ b/protocol/proto/playlist4meta.proto @@ -1,58 +1,50 @@ message ListChecksum { - required int32 version = 1; - optional bytes sha1 = 4; + optional int32 version = 0x1; + optional bytes sha1 = 0x4; } + message DownloadFormat { - enum Codec { - CODEC_UNKNOWN = 0; - OGG_VORBIS = 1; - FLAC = 2; - MPEG_1_LAYER_3 = 3; - } - required Codec codec = 1; -} -enum ListAttributeKind { - LIST_UNKNOWN = 0; - LIST_NAME = 1; - LIST_DESCRIPTION = 2; - LIST_PICTURE = 3; - LIST_COLLABORATIVE = 4; - LIST_PL3_VERSION = 5; - LIST_DELETED_BY_OWNER = 6; - LIST_RESTRICTED_COLLABORATIVE = 7; + optional Codec codec = 0x1; + enum Codec { + CODEC_UNKNOWN = 0x0; + OGG_VORBIS = 0x1; + FLAC = 0x2; + MPEG_1_LAYER_3 = 0x3; + } } + message ListAttributes { - optional string name = 1; - optional string description = 2; - optional bytes picture = 3; - optional bool collaborative = 4; - optional string pl3_version = 5; - optional bool deleted_by_owner = 6; - optional bool restricted_collaborative = 7; -} -enum ItemAttributeKind { - ITEM_UNKNOWN = 0; - ITEM_ADDED_BY = 1; - ITEM_TIMESTAMP = 2; - ITEM_MESSAGE = 3; - ITEM_SEEN = 4; - ITEM_DOWNLOAD_COUNT = 5; - ITEM_DOWNLOAD_FORMAT = 6; - ITEM_SEVENDIGITAL_ID = 7; - ITEM_SEVENDIGITAL_LEFT = 8; - ITEM_SEEN_AT = 9; + optional string name = 0x1; + optional string description = 0x2; + optional bytes picture = 0x3; + optional bool collaborative = 0x4; + optional string pl3_version = 0x5; + optional bool deleted_by_owner = 0x6; + optional bool restricted_collaborative = 0x7; + optional int64 deprecated_client_id = 0x8; + optional bool public_starred = 0x9; + optional string client_id = 0xa; } + message ItemAttributes { - optional string added_by = 1; - optional string message = 3; - optional bool seen = 4; - optional DownloadFormat download_format = 6; - optional string sevendigital_id = 7; + optional string added_by = 0x1; + optional int64 timestamp = 0x2; + optional string message = 0x3; + optional bool seen = 0x4; + optional int64 download_count = 0x5; + optional DownloadFormat download_format = 0x6; + optional string sevendigital_id = 0x7; + optional int64 sevendigital_left = 0x8; + optional int64 seen_at = 0x9; + optional bool public = 0xa; } + message StringAttribute { - required string key = 1; - required string value = 2; + optional string key = 0x1; + optional string value = 0x2; } + message StringAttributes { - repeated StringAttribute attribute = 1; + repeated StringAttribute attribute = 0x1; } + diff --git a/protocol/proto/playlist4ops.proto b/protocol/proto/playlist4ops.proto index cd65a648..d1595712 100644 --- a/protocol/proto/playlist4ops.proto +++ b/protocol/proto/playlist4ops.proto @@ -1,68 +1,101 @@ -import "playlist4content.proto"; import "playlist4meta.proto"; +import "playlist4content.proto"; message Add { - optional int32 fromIndex = 1; - repeated Item items = 2; - optional ListChecksum list_checksum = 3; - optional bool addLast = 4; - optional bool addFirst = 5; + optional int32 fromIndex = 0x1; + repeated Item items = 0x2; + optional ListChecksum list_checksum = 0x3; + optional bool addLast = 0x4; + optional bool addFirst = 0x5; } + message Rem { - optional int32 fromIndex = 1; - optional int32 length = 2; - repeated Item items = 3; - optional ListChecksum list_checksum = 4; - optional ListChecksum items_checksum = 5; - optional ListChecksum uris_checksum = 6; - optional bool itemsAsKey = 7; + optional int32 fromIndex = 0x1; + optional int32 length = 0x2; + repeated Item items = 0x3; + optional ListChecksum list_checksum = 0x4; + optional ListChecksum items_checksum = 0x5; + optional ListChecksum uris_checksum = 0x6; + optional bool itemsAsKey = 0x7; } + message Mov { - required int32 fromIndex = 1; - required int32 length = 2; - required int32 toIndex = 3; - optional ListChecksum list_checksum = 4; - optional ListChecksum items_checksum = 5; - optional ListChecksum uris_checksum = 6; + optional int32 fromIndex = 0x1; + optional int32 length = 0x2; + optional int32 toIndex = 0x3; + optional ListChecksum list_checksum = 0x4; + optional ListChecksum items_checksum = 0x5; + optional ListChecksum uris_checksum = 0x6; } + message ItemAttributesPartialState { - required ItemAttributes values = 1; - repeated ItemAttributeKind no_value = 2; + optional ItemAttributes values = 0x1; + repeated ItemAttributeKind no_value = 0x2; + + enum ItemAttributeKind { + ITEM_UNKNOWN = 0x0; + ITEM_ADDED_BY = 0x1; + ITEM_TIMESTAMP = 0x2; + ITEM_MESSAGE = 0x3; + ITEM_SEEN = 0x4; + ITEM_DOWNLOAD_COUNT = 0x5; + ITEM_DOWNLOAD_FORMAT = 0x6; + ITEM_SEVENDIGITAL_ID = 0x7; + ITEM_SEVENDIGITAL_LEFT = 0x8; + ITEM_SEEN_AT = 0x9; + ITEM_PUBLIC = 0xa; + } } + message ListAttributesPartialState { - required ListAttributes values = 1; - repeated ListAttributeKind no_value = 2; + optional ListAttributes values = 0x1; + repeated ListAttributeKind no_value = 0x2; + + enum ListAttributeKind { + LIST_UNKNOWN = 0x0; + LIST_NAME = 0x1; + LIST_DESCRIPTION = 0x2; + LIST_PICTURE = 0x3; + LIST_COLLABORATIVE = 0x4; + LIST_PL3_VERSION = 0x5; + LIST_DELETED_BY_OWNER = 0x6; + LIST_RESTRICTED_COLLABORATIVE = 0x7; + } } + message UpdateItemAttributes { - required int32 index = 1; - required ItemAttributesPartialState new_attributes = 2; - optional ItemAttributesPartialState old_attributes = 3; - optional ListChecksum list_checksum = 4; - optional ListChecksum old_attributes_checksum = 5; + optional int32 index = 0x1; + optional ItemAttributesPartialState new_attributes = 0x2; + optional ItemAttributesPartialState old_attributes = 0x3; + optional ListChecksum list_checksum = 0x4; + optional ListChecksum old_attributes_checksum = 0x5; } + message UpdateListAttributes { - required ListAttributesPartialState new_attributes = 1; - optional ListAttributesPartialState old_attributes = 2; - optional ListChecksum list_checksum = 3; - optional ListChecksum old_attributes_checksum = 4; + optional ListAttributesPartialState new_attributes = 0x1; + optional ListAttributesPartialState old_attributes = 0x2; + optional ListChecksum list_checksum = 0x3; + optional ListChecksum old_attributes_checksum = 0x4; } + message Op { - enum Kind { - KIND_UNKNOWN = 0; - ADD = 2; - REM = 3; - MOV = 4; - UPDATE_ITEM_ATTRIBUTES = 5; - UPDATE_LIST_ATTRIBUTES = 6; - }; - required Kind kind = 1; - optional Add add = 2; - optional Rem rem = 3; - optional Mov mov = 4; - optional UpdateItemAttributes update_item_attributes = 5; - optional UpdateListAttributes update_list_attributes = 6; + optional Kind kind = 0x1; + enum Kind { + KIND_UNKNOWN = 0x0; + ADD = 0x2; + REM = 0x3; + MOV = 0x4; + UPDATE_ITEM_ATTRIBUTES = 0x5; + UPDATE_LIST_ATTRIBUTES = 0x6; + } + optional Add add = 0x2; + optional Rem rem = 0x3; + optional Mov mov = 0x4; + optional UpdateItemAttributes update_item_attributes = 0x5; + optional UpdateListAttributes update_list_attributes = 0x6; } message OpList { - repeated Op ops = 1; + repeated Op ops = 0x1; } + diff --git a/protocol/proto/playlist4service.proto b/protocol/proto/playlist4service.proto deleted file mode 100644 index 2f038f83..00000000 --- a/protocol/proto/playlist4service.proto +++ /dev/null @@ -1,118 +0,0 @@ -import "playlist4changes.proto"; -import "playlist4content.proto"; - -message RequestContext { - optional bool administrative = 2; - optional bool migration = 4; - optional string tag = 7; - optional bool useStarredView = 8; - optional bool syncWithPublished = 9; -} -message GetCurrentRevisionArgs { - optional bytes uri = 1; - optional RequestContext context = 2; -} -message GetChangesInSequenceRangeArgs { - optional bytes uri = 1; - optional RequestContext context = 2; - optional int32 fromSequenceNumber = 3; - optional int32 toSequenceNumber = 4; -} -message GetChangesInSequenceRangeMatchingPl3VersionArgs { - optional bytes uri = 1; - optional RequestContext context = 2; - optional int32 fromSequenceNumber = 3; - optional int32 toSequenceNumber = 4; - optional string pl3Version = 5; -} -message GetChangesInSequenceRangeReturn { - repeated RevisionTaggedChangeSet result = 1; -} -message ObliterateListArgs { - optional bytes uri = 1; - optional RequestContext context = 2; -} -message UpdatePublishedArgs { - optional bytes publishedUri = 1; - optional RequestContext context = 2; - optional bytes uri = 3; - optional bool isPublished = 4; -} -message SynchronizeArgs { - optional bytes uri = 1; - optional RequestContext context = 2; - optional ListContentSelection selection = 3; - optional ListChanges changes = 4; -} -message GetSnapshotAtRevisionArgs { - optional bytes uri = 1; - optional RequestContext context = 2; - optional bytes revision = 3; -} -message SubscribeRequest { - repeated bytes uris = 1; -} -message UnsubscribeRequest { - repeated bytes uris = 1; -} -enum Playlist4InboxErrorKind { - INBOX_NOT_ALLOWED = 2; - INBOX_INVALID_USER = 3; - INBOX_INVALID_URI = 4; - INBOX_LIST_TOO_LONG = 5; -} -message Playlist4ServiceException { - optional string why = 1; - optional string symbol = 2; - optional bool permanent = 3; - optional string serviceErrorClass = 4; - optional Playlist4InboxErrorKind inboxErrorKind = 5; -} -message SynchronizeReturn { - optional SelectedListContent result = 1; - optional Playlist4ServiceException exception = 4; -} -enum Playlist4ServiceMethodKind { - METHOD_UNKNOWN = 0; - METHOD_GET_CURRENT_REVISION = 2; - METHOD_GET_CHANGES_IN_SEQUENCE_RANGE = 3; - METHOD_OBLITERATE_LIST = 4; - METHOD_SYNCHRONIZE = 5; - METHOD_UPDATE_PUBLISHED = 6; - METHOD_GET_CHANGES_IN_SEQUENCE_RANGE_MATCHING_PL3_VERSION = 7; - METHOD_GET_SNAPSHOT_AT_REVISION = 8; -} -message Playlist4ServiceCall { - optional Playlist4ServiceMethodKind kind = 1; - optional GetCurrentRevisionArgs getCurrentRevisionArgs = 2; - optional GetChangesInSequenceRangeArgs getChangesInSequenceRangeArgs = 3; - optional ObliterateListArgs obliterateListArgs = 4; - optional SynchronizeArgs synchronizeArgs = 5; - optional UpdatePublishedArgs updatePublishedArgs = 6; - optional GetChangesInSequenceRangeMatchingPl3VersionArgs getChangesInSequenceRangeMatchingPl3VersionArgs = 7; - optional GetSnapshotAtRevisionArgs getSnapshotAtRevisionArgs = 8; -} -message Playlist4ServiceReturn { - optional Playlist4ServiceMethodKind kind = 1; - optional Playlist4ServiceException exception = 2; - optional bytes getCurrentRevisionReturn = 3; - optional GetChangesInSequenceRangeReturn getChangesInSequenceRangeReturn = 4; - optional bool obliterateListReturn = 5; - optional SynchronizeReturn synchronizeReturn = 6; - optional bool updatePublishedReturn = 7; - optional GetChangesInSequenceRangeReturn getChangesInSequenceRangeMatchingPl3VersionReturn = 8; - //optional RevisionTaggedListSnapshot getSnapshotAtRevisionReturn = 9; - optional bytes getSnapshotAtRevisionReturn = 9; -} -message CreateListReply { - required bytes uri = 1; - optional bytes revision = 2; -} -message ModifyReply { - required bytes uri = 1; - optional bytes revision = 2; -} -message PlaylistModificationInfo { - optional bytes uri = 1; - optional bytes new_revision = 2; -} diff --git a/protocol/proto/popcount.proto b/protocol/proto/popcount.proto new file mode 100644 index 00000000..3b2d1a36 --- /dev/null +++ b/protocol/proto/popcount.proto @@ -0,0 +1,11 @@ +message PopcountRequest { +} + +message PopcountResult { + optional sint64 count = 0x1; + optional bool truncated = 0x2; + repeated string user = 0x3; + repeated sint64 subscriptionTimestamps = 0x4; + repeated sint64 insertionTimestamps = 0x5; +} + diff --git a/protocol/proto/presence.proto b/protocol/proto/presence.proto new file mode 100644 index 00000000..f74ba5f5 --- /dev/null +++ b/protocol/proto/presence.proto @@ -0,0 +1,92 @@ +message PlaylistPublishedState { + optional string uri = 0x1; + optional int64 timestamp = 0x2; +} + +message PlaylistTrackAddedState { + optional string playlist_uri = 0x1; + optional string track_uri = 0x2; + optional int64 timestamp = 0x3; +} + +message TrackFinishedPlayingState { + optional string uri = 0x1; + optional string context_uri = 0x2; + optional int64 timestamp = 0x3; + optional string referrer_uri = 0x4; +} + +message FavoriteAppAddedState { + optional string app_uri = 0x1; + optional int64 timestamp = 0x2; +} + +message TrackStartedPlayingState { + optional string uri = 0x1; + optional string context_uri = 0x2; + optional int64 timestamp = 0x3; + optional string referrer_uri = 0x4; +} + +message UriSharedState { + optional string uri = 0x1; + optional string message = 0x2; + optional int64 timestamp = 0x3; +} + +message ArtistFollowedState { + optional string uri = 0x1; + optional string artist_name = 0x2; + optional string artist_cover_uri = 0x3; + optional int64 timestamp = 0x4; +} + +message DeviceInformation { + optional string os = 0x1; + optional string type = 0x2; +} + +message GenericPresenceState { + optional int32 type = 0x1; + optional int64 timestamp = 0x2; + optional string item_uri = 0x3; + optional string item_name = 0x4; + optional string item_image = 0x5; + optional string context_uri = 0x6; + optional string context_name = 0x7; + optional string context_image = 0x8; + optional string referrer_uri = 0x9; + optional string referrer_name = 0xa; + optional string referrer_image = 0xb; + optional string message = 0xc; + optional DeviceInformation device_information = 0xd; +} + +message State { + optional int64 timestamp = 0x1; + optional Type type = 0x2; + enum Type { + PLAYLIST_PUBLISHED = 0x1; + PLAYLIST_TRACK_ADDED = 0x2; + TRACK_FINISHED_PLAYING = 0x3; + FAVORITE_APP_ADDED = 0x4; + TRACK_STARTED_PLAYING = 0x5; + URI_SHARED = 0x6; + ARTIST_FOLLOWED = 0x7; + GENERIC = 0xb; + } + optional string uri = 0x3; + optional PlaylistPublishedState playlist_published = 0x4; + optional PlaylistTrackAddedState playlist_track_added = 0x5; + optional TrackFinishedPlayingState track_finished_playing = 0x6; + optional FavoriteAppAddedState favorite_app_added = 0x7; + optional TrackStartedPlayingState track_started_playing = 0x8; + optional UriSharedState uri_shared = 0x9; + optional ArtistFollowedState artist_followed = 0xa; + optional GenericPresenceState generic = 0xb; +} + +message StateList { + repeated State states = 0x1; +} + diff --git a/protocol/proto/pubsub.proto b/protocol/proto/pubsub.proto new file mode 100644 index 00000000..94c2cd91 --- /dev/null +++ b/protocol/proto/pubsub.proto @@ -0,0 +1,6 @@ +message Subscription { + optional string uri = 0x1; + optional int32 expiry = 0x2; + optional int32 status_code = 0x3; +} + diff --git a/protocol/proto/radio.proto b/protocol/proto/radio.proto new file mode 100644 index 00000000..b21aad2c --- /dev/null +++ b/protocol/proto/radio.proto @@ -0,0 +1,56 @@ +message RadioRequest { + repeated string uris = 0x1; + optional int32 salt = 0x2; + optional int32 length = 0x4; + optional string stationId = 0x5; + repeated string lastTracks = 0x6; +} + +message MultiSeedRequest { + repeated string uris = 0x1; +} + +message Feedback { + optional string uri = 0x1; + optional string type = 0x2; + optional double timestamp = 0x3; +} + +message Tracks { + repeated string gids = 0x1; + optional string source = 0x2; + optional string identity = 0x3; + repeated string tokens = 0x4; + repeated Feedback feedback = 0x5; +} + +message Station { + optional string id = 0x1; + optional string title = 0x2; + optional string titleUri = 0x3; + optional string subtitle = 0x4; + optional string subtitleUri = 0x5; + optional string imageUri = 0x6; + optional double lastListen = 0x7; + repeated string seeds = 0x8; + optional int32 thumbsUp = 0x9; + optional int32 thumbsDown = 0xa; +} + +message Rules { + optional string js = 0x1; +} + +message StationResponse { + optional Station station = 0x1; + repeated Feedback feedback = 0x2; +} + +message StationList { + repeated Station stations = 0x1; +} + +message LikedPlaylist { + optional string uri = 0x1; +} + diff --git a/protocol/proto/search.proto b/protocol/proto/search.proto new file mode 100644 index 00000000..776cb0ad --- /dev/null +++ b/protocol/proto/search.proto @@ -0,0 +1,42 @@ +message SearchRequest { + optional string query = 0x1; + optional Type type = 0x2; + enum Type { + TRACK = 0x0; + ALBUM = 0x1; + ARTIST = 0x2; + PLAYLIST = 0x3; + USER = 0x4; + } + optional int32 limit = 0x3; + optional int32 offset = 0x4; + optional bool did_you_mean = 0x5; + optional string spotify_uri = 0x2; + repeated bytes file_id = 0x3; + optional string url = 0x4; + optional string slask_id = 0x5; +} + +message Playlist { + optional string uri = 0x1; + optional string name = 0x2; + repeated Image image = 0x3; +} + +message User { + optional string username = 0x1; + optional string full_name = 0x2; + repeated Image image = 0x3; + optional sint32 followers = 0x4; +} + +message SearchReply { + optional sint32 hits = 0x1; + repeated Track track = 0x2; + repeated Album album = 0x3; + repeated Artist artist = 0x4; + repeated Playlist playlist = 0x5; + optional string did_you_mean = 0x6; + repeated User user = 0x7; +} + diff --git a/protocol/proto/social.proto b/protocol/proto/social.proto new file mode 100644 index 00000000..542cfb69 --- /dev/null +++ b/protocol/proto/social.proto @@ -0,0 +1,10 @@ +message DecorationData { + optional string username = 0x1; + optional string full_name = 0x2; + optional string image_url = 0x3; + optional string large_image_url = 0x5; + optional string first_name = 0x6; + optional string last_name = 0x7; + optional string facebook_uid = 0x8; +} + diff --git a/protocol/proto/socialgraph.proto b/protocol/proto/socialgraph.proto new file mode 100644 index 00000000..2be79106 --- /dev/null +++ b/protocol/proto/socialgraph.proto @@ -0,0 +1,47 @@ +message CountReply { + repeated int32 counts = 0x1; +} + +message UserListRequest { + optional string last_result = 0x1; + optional int32 count = 0x2; + optional bool include_length = 0x3; +} + +message UserListReply { + repeated User users = 0x1; + optional int32 length = 0x2; +} + +message User { + optional string username = 0x1; + optional int32 subscriber_count = 0x2; + optional int32 subscription_count = 0x3; +} + +message ArtistListReply { + repeated Artist artists = 0x1; +} + +message Artist { + optional string artistid = 0x1; + optional int32 subscriber_count = 0x2; +} + +message StringListRequest { + repeated string args = 0x1; +} + +message StringListReply { + repeated string reply = 0x1; +} + +message TopPlaylistsRequest { + optional string username = 0x1; + optional int32 count = 0x2; +} + +message TopPlaylistsReply { + repeated string uris = 0x1; +} + diff --git a/protocol/proto/spirc.proto b/protocol/proto/spirc.proto index ad55c388..1bef6e14 100644 --- a/protocol/proto/spirc.proto +++ b/protocol/proto/spirc.proto @@ -1,92 +1,118 @@ -enum MessageType { - kMessageTypeHello = 1; - kMessageTypeGoodbye = 2; - kMessageTypeNotify = 10; - kMessageTypeLoad = 20; - kMessageTypePlay = 21; - kMessageTypePause = 22; -// kMessageTypePlayPause = 23; - kMessageTypeSeek = 24; - kMessageTypePrev = 25; - kMessageTypeNext = 26; - kMessageTypeVolume = 27; - kMessageTypeShuffle = 28; - kMessageTypeRepeat = 29; - kMessageTypeQueue = 30; - kMessageTypeVolumeDown = 31; - kMessageTypeVolumeUp = 32; - kMessageTypeAddToQueue = 33; -} -enum PlayStatus { - kPlayStatusStop = 0; - kPlayStatusPlay = 1; - kPlayStatusPause = 2; - kPlayStatusLoading = 3; - kPlayStatusError = 4; -} -message Goodbye { - required string reason = 1; -} -message State { - optional string contextURI = 0x2; - optional uint32 index = 0x3; - optional uint32 position = 0x4; - optional PlayStatus status = 0x5; - - optional uint64 timestamp = 0x7; - optional string context_name = 0x8; - optional uint32 duration = 0x9; - optional uint32 data9 = 0xa; - repeated uint64 data10 = 0xb; - optional bool shuffle = 0xd; - optional bool repeat = 0xe; - - optional string data12 = 0x14; - optional uint32 data13 = 0x15; - optional uint32 data14 = 0x18; - optional uint32 data15 = 0x19; - optional uint32 data16 = 0x1a; - repeated QueuedTrack queued = 0x1b; - message QueuedTrack { - optional bytes gid = 0x1; - optional string local_uri = 0x2; - optional uint32 data1 = 0x3; - } -} - message Frame { - required uint32 version = 1; - required string source = 2; - required string version_string = 3; - required uint32 msgid = 4; - required uint32 type = 5; - - required DeviceInfo device = 0x7; - - //required Goodbye goodbye = 0xb; + optional uint32 version = 0x1; + optional string ident = 0x2; + optional string protocol_version = 0x3; + optional uint32 seq_nr = 0x4; + optional MessageType typ = 0x5; + optional DeviceState device_state = 0x7; + optional Goodbye goodbye = 0xb; optional State state = 0xc; - optional uint32 position = 0xd; optional uint32 volume = 0xe; - - optional uint64 timestamp = 0x11; - optional string destination = 0x12; - - message DeviceInfo { - optional string version = 0x1; - required bool active = 0xa; - required bool foreground = 0xb; - required uint32 volume = 0xc; - required string name = 0xd; - optional uint32 data15 = 0xe; - required uint64 activeTime = 0xf; - repeated Data17 data17 = 0x11; - - message Data17 { - required uint32 data0 = 0x1; - optional uint32 data1 = 0x2; - repeated string data2 = 0x3; - } - } + optional int64 state_update_id = 0x11; + repeated string recipient = 0x12; + optional bytes context_player_state = 0x13; +} + +enum MessageType { + kMessageTypeHello = 0x1; + kMessageTypeGoodbye = 0x2; + kMessageTypeProbe = 0x3; + kMessageTypeNotify = 0xa; + kMessageTypeLoad = 0x14; + kMessageTypePlay = 0x15; + kMessageTypePause = 0x16; + kMessageTypePlayPause = 0x17; + kMessageTypeSeek = 0x18; + kMessageTypePrev = 0x19; + kMessageTypeNext = 0x1a; + kMessageTypeVolume = 0x1b; + kMessageTypeShuffle = 0x1c; + kMessageTypeRepeat = 0x1d; + kMessageTypeVolumeDown = 0x1f; + kMessageTypeVolumeUp = 0x20; + kMessageTypeReplace = 0x21; + kMessageTypeLogout = 0x22; + kMessageTypeAction = 0x23; +} + +message DeviceState { + optional string sw_version = 0x1; + optional bool is_active = 0xa; + optional bool can_play = 0xb; + optional uint32 volume = 0xc; + optional string name = 0xd; + optional uint32 error_code = 0xe; + optional int64 became_active_at = 0xf; + optional string error_message = 0x10; + repeated Capability capabilities = 0x11; + repeated string local_uris = 0x12; + repeated int32 enc_key = 0x13; +} + +message Capability { + optional CapabilityType typ = 0x1; + repeated int64 intValue = 0x2; + repeated string stringValue = 0x3; +} + +enum CapabilityType { + kSupportedContexts = 0x1; + kCanBePlayer = 0x2; + kRestrictToLocal = 0x3; + kDeviceType = 0x4; + kGaiaEqConnectId = 0x5; + kSupportsLogout = 0x6; + kIsObservable = 0x7; + kVolumeSteps = 0x8; + kSupportedTypes = 0x9; +} + +message Goodbye { + optional string reason = 0x1; +} + +message State { + optional string context_uri = 0x2; + optional uint32 index = 0x3; + optional uint32 position_ms = 0x4; + optional PlayStatus status = 0x5; + optional uint64 position_measured_at = 0x7; + optional string context_description = 0x8; + optional bool shuffle = 0xd; + optional bool repeat = 0xe; + optional string last_command_ident = 0x14; + optional uint32 last_command_msgid = 0x15; + optional bool playing_from_fallback = 0x18; + optional uint32 row = 0x19; + optional uint32 playing_track_index = 0x1a; + repeated TrackRef track = 0x1b; + optional Ad ad = 0x1c; +} + +enum PlayStatus { + kPlayStatusStop = 0x0; + kPlayStatusPlay = 0x1; + kPlayStatusPause = 0x2; + kPlayStatusLoading = 0x3; +} + +message TrackRef { + optional bytes gid = 0x1; + optional string uri = 0x2; + optional bool queued = 0x3; + optional string context = 0x4; +} + +message Ad { + optional int32 next = 0x1; + optional bytes ogg_fid = 0x2; + optional bytes image_fid = 0x3; + optional int32 duration = 0x4; + optional string click_url = 0x5; + optional string impression_url = 0x6; + optional string product = 0x7; + optional string advertiser = 0x8; + optional bytes gid = 0x9; } diff --git a/protocol/proto/spotify.proto b/protocol/proto/spotify.proto deleted file mode 100644 index e69de29b..00000000 diff --git a/protocol/proto/suggest.proto b/protocol/proto/suggest.proto new file mode 100644 index 00000000..1b88977e --- /dev/null +++ b/protocol/proto/suggest.proto @@ -0,0 +1,41 @@ +message Track { + optional bytes gid = 0x1; + optional string name = 0x2; + optional bytes image = 0x3; + repeated string artist_name = 0x4; + repeated bytes artist_gid = 0x5; + optional uint32 rank = 0x6; +} + +message Artist { + optional bytes gid = 0x1; + optional string name = 0x2; + optional bytes image = 0x3; + optional uint32 rank = 0x6; +} + +message Album { + optional bytes gid = 0x1; + optional string name = 0x2; + optional bytes image = 0x3; + repeated string artist_name = 0x4; + repeated bytes artist_gid = 0x5; + optional uint32 rank = 0x6; +} + +message Playlist { + optional string uri = 0x1; + optional string name = 0x2; + optional string image_uri = 0x3; + optional string owner_name = 0x4; + optional string owner_uri = 0x5; + optional uint32 rank = 0x6; +} + +message Suggestions { + repeated Track track = 0x1; + repeated Album album = 0x2; + repeated Artist artist = 0x3; + repeated Playlist playlist = 0x4; +} + diff --git a/protocol/proto/toplist.proto b/protocol/proto/toplist.proto new file mode 100644 index 00000000..c4073830 --- /dev/null +++ b/protocol/proto/toplist.proto @@ -0,0 +1,4 @@ +message Toplist { + repeated string items = 0x1; +} + diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index bfb8406e..7fdd65dd 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -7,11 +7,5 @@ mod_path! keyexchange (concat!(env!("OUT_DIR"), "/keyexchange.rs")); mod_path! authentication (concat!(env!("OUT_DIR"), "/authentication.rs")); mod_path! mercury (concat!(env!("OUT_DIR"), "/mercury.rs")); mod_path! metadata (concat!(env!("OUT_DIR"), "/metadata.rs")); - -mod_path! playlist4changes (concat!(env!("OUT_DIR"), "/playlist4changes.rs")); -mod_path! playlist4content (concat!(env!("OUT_DIR"), "/playlist4content.rs")); -mod_path! playlist4issues (concat!(env!("OUT_DIR"), "/playlist4issues.rs")); -mod_path! playlist4meta (concat!(env!("OUT_DIR"), "/playlist4meta.rs")); -mod_path! playlist4ops (concat!(env!("OUT_DIR"), "/playlist4ops.rs")); -mod_path! playlist4service (concat!(env!("OUT_DIR"), "/playlist4service.rs")); +mod_path! spirc (concat!(env!("OUT_DIR"), "/spirc.rs")); diff --git a/src/main.rs b/src/main.rs index 53e2e95c..cbadbc88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ #![crate_name = "librespot"] -#![feature(alloc,plugin,core,collections,std_misc,zero_one)] +#![feature(plugin,zero_one,iter_arith,slice_position_elem,slice_bytes,bitset,mpsc_select,arc_weak,append)] #![plugin(protobuf_macros)] #[macro_use] extern crate lazy_static; @@ -62,6 +62,16 @@ fn main() { session.poll(); let mut cache = MetadataCache::new(session.metadata.clone()); + + + print_track(&mut cache, track_id); + + loop { + session.poll(); + } +} + +fn print_track(cache: &mut MetadataCache, track_id: SpotifyId) { let track : TrackRef = cache.get(track_id); let album : AlbumRef = { @@ -85,11 +95,5 @@ fn main() { let data = handle.unwrap(); eprintln!("{}", data.name); } - - Player::play(&session, track); - - loop { - session.poll(); - } } diff --git a/src/mercury.rs b/src/mercury.rs index 8846f05c..abe1eb91 100644 --- a/src/mercury.rs +++ b/src/mercury.rs @@ -12,23 +12,23 @@ use librespot_protocol as protocol; use subsystem::Subsystem; use util::Either::{Left, Right}; +#[derive(Debug, PartialEq, Eq)] pub enum MercuryMethod { GET, - GETX, SUB, UNSUB, } pub struct MercuryRequest { pub method: MercuryMethod, - pub url: String, - pub mime: Option, + pub uri: String, + pub content_type: Option, pub callback: MercuryCallback } #[derive(Debug)] pub struct MercuryResponse { - pub url: String, + pub uri: String, pub payload: LinkedList> } @@ -53,7 +53,6 @@ impl fmt::Display for MercuryMethod { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { formatter.write_str(match *self { MercuryMethod::GET => "GET", - MercuryMethod::GETX => "GETX", MercuryMethod::SUB => "SUB", MercuryMethod::UNSUB => "UNSUB" }) @@ -83,8 +82,14 @@ impl MercuryManager { self.next_seq += 1; let data = self.encode_request(&seq, &req); + let cmd = match req.method { + MercuryMethod::SUB => 0xb3, + MercuryMethod::UNSUB => 0xb4, + _ => 0xb2, + }; + self.packet_tx.send(Packet { - cmd: 0xb2, + cmd: cmd, data: data }).unwrap(); @@ -103,29 +108,24 @@ impl MercuryManager { buffer } - fn complete_request(&mut self, seq: &[u8]) { - let mut pending = self.pending.remove(seq).unwrap(); - + fn complete_request(&mut self, cmd: u8, mut pending: MercuryPending) { let header_data = match pending.parts.pop_front() { Some(data) => data, None => panic!("No header part !") }; - let header : protocol::mercury::MercuryReply = + let header : protocol::mercury::Header = protobuf::parse_from_bytes(&header_data).unwrap(); - match pending.callback { - Some(ch) => { - ch.send(MercuryResponse{ - url: header.get_url().to_string(), - payload: pending.parts - }).unwrap(); - } - None => (), + if let Some(ref ch) = pending.callback { + ch.send(MercuryResponse{ + uri: header.get_uri().to_string(), + payload: pending.parts + }).unwrap(); } } - fn handle_packet(&mut self, _cmd: u8, data: Vec) { + fn handle_packet(&mut self, cmd: u8, data: Vec) { let mut packet = Cursor::new(data); let seq = { @@ -137,30 +137,37 @@ impl MercuryManager { let flags = packet.read_u8().unwrap(); let count = packet.read_u16::().unwrap() as usize; - { - let pending : &mut MercuryPending = match self.pending.get_mut(&seq) { - Some(pending) => pending, - None => { return; } - }; + let mut pending = if let Some(pending) = self.pending.remove(&seq) { + pending + } else if cmd == 0xb5 { + MercuryPending { + parts: LinkedList::new(), + partial: None, + callback: None, + } + } else { + println!("Ignore seq {:?} cmd {}", seq, cmd); + return + }; - for i in 0..count { - let mut part = Self::parse_part(&mut packet); - if pending.partial.is_some() { - let mut data = replace(&mut pending.partial, None).unwrap(); - data.append(&mut part); - part = data; - } + for i in 0..count { + let mut part = Self::parse_part(&mut packet); + if let Some(mut data) = replace(&mut pending.partial, None) { + data.append(&mut part); + part = data; + } - if i == count -1 && (flags == 2) { - pending.partial = Some(part) - } else { - pending.parts.push_back(part); - } + if i == count - 1 && (flags == 2) { + pending.partial = Some(part) + } else { + pending.parts.push_back(part); } } if flags == 0x1 { - self.complete_request(&seq); + self.complete_request(cmd, pending); + } else { + self.pending.insert(seq, pending); } } @@ -171,11 +178,13 @@ impl MercuryManager { packet.write_u8(1).unwrap(); // Flags: FINAL packet.write_u16::(1).unwrap(); // Part count. Only header - let mut header = protobuf_init!(protocol::mercury::MercuryRequest::new(), { - url: req.url.clone(), + let mut header = protobuf_init!(protocol::mercury::Header::new(), { + uri: req.uri.clone(), method: req.method.to_string(), }); - req.mime.clone().map(|mime| header.set_mime(mime)); + if let Some(ref content_type) = req.content_type { + header.set_content_type(content_type.clone()); + } packet.write_u16::(header.compute_size() as u16).unwrap(); header.write_to_writer(&mut packet).unwrap(); diff --git a/src/metadata.rs b/src/metadata.rs index 7338d1df..0f254f17 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -34,7 +34,7 @@ impl MetadataTrait for Track { files: msg.get_file().iter() .map(|file| { let mut dst = [0u8; 20]; - copy_memory(&file.get_gid(), &mut dst); + copy_memory(&file.get_file_id(), &mut dst); dst }) .collect(), @@ -235,8 +235,8 @@ impl MetadataManager { mercury.send(MercuryRequest { method: MercuryMethod::GET, - url: format!("{}/{}", T::base_url(), object.id.to_base16()), - mime: None, + uri: format!("{}/{}", T::base_url(), object.id.to_base16()), + content_type: None, callback: Some(tx) }).unwrap();