moving some modules around

This commit is contained in:
cere 2024-02-21 01:32:58 -05:00
parent 70734c7c59
commit 75bfe0dae2
57 changed files with 7 additions and 3 deletions

View file

@ -0,0 +1,34 @@
from __future__ import annotations
from librespot.crypto import DiffieHellman
from librespot.proto.Keyexchange_pb2 import BuildInfo, Platform, Product, ProductFlags
from librespot.structure import Closeable, Runnable
import platform
class Version:
version_name = "0.0.9"
@staticmethod
def platform() -> Platform:
if platform.system() == "Windows":
return Platform.PLATFORM_WIN32_X86
if platform.system() == "Darwin":
return Platform.PLATFORM_OSX_X86
return Platform.PLATFORM_LINUX_X86
@staticmethod
def version_string():
return "librespot-python " + Version.version_name
@staticmethod
def system_info_string():
return Version.version_string() + \
"; Python " + platform.python_version() + \
"; " + platform.system()
@staticmethod
def standard_build_info() -> BuildInfo:
return BuildInfo(product=Product.PRODUCT_CLIENT,
product_flags=[ProductFlags.PRODUCT_FLAG_NONE],
platform=Version.platform(),
version=117300517)

View file

@ -0,0 +1,912 @@
from __future__ import annotations
from librespot import util
from librespot.audio.decrypt import AesAudioDecrypt
from librespot.audio.format import SuperAudioFormat
from librespot.audio.storage import ChannelManager
from librespot.cache import CacheManager
from librespot.crypto import Packet
from librespot.metadata import EpisodeId, PlayableId, TrackId
from librespot.proto import Metadata_pb2 as Metadata, StorageResolve_pb2 as StorageResolve
from librespot.structure import AudioDecrypt, AudioQualityPicker, Closeable, FeederException, GeneralAudioStream, GeneralWritableStream, HaltListener, NoopAudioDecrypt, PacketsReceiver
import concurrent.futures
import io
import logging
import math
import queue
import random
import struct
import threading
import time
import typing
import urllib.parse
if typing.TYPE_CHECKING:
from librespot.core import Session
class AbsChunkedInputStream(io.BytesIO, HaltListener):
chunk_exception = None
closed = False
max_chunk_tries = 128
preload_ahead = 3
preload_chunk_retries = 2
retries: typing.List[int]
retry_on_chunk_error: bool
wait_lock: threading.Condition = threading.Condition()
wait_for_chunk = -1
__decoded_length = 0
__mark = 0
__pos = 0
def __init__(self, retry_on_chunk_error: bool):
super().__init__()
self.retries = [0] * self.chunks()
self.retry_on_chunk_error = retry_on_chunk_error
def is_closed(self) -> bool:
return self.closed
def buffer(self) -> typing.List[bytes]:
raise NotImplementedError()
def size(self) -> int:
raise NotImplementedError()
def close(self) -> None:
self.closed = True
with self.wait_lock:
self.wait_lock.notify_all()
def available(self):
return self.size() - self.__pos
def mark_supported(self) -> bool:
return True
def mark(self, read_ahead_limit: int) -> None:
self.__mark = self.__pos
def reset(self) -> None:
self.__pos = self.__mark
def pos(self) -> int:
return self.__pos
def seek(self, where: int, **kwargs) -> None:
if where < 0:
raise TypeError()
if self.closed:
raise IOError("Stream is closed!")
self.__pos = where
self.check_availability(int(self.__pos / (128 * 1024)), False, False)
def skip(self, n: int) -> int:
if n < 0:
raise TypeError()
if self.closed:
raise IOError("Stream is closed!")
k = self.size() - self.__pos
if n < k:
k = n
self.__pos += k
chunk = int(self.__pos / (128 * 1024))
self.check_availability(chunk, False, False)
return k
def requested_chunks(self) -> typing.List[bool]:
raise NotImplementedError()
def available_chunks(self) -> typing.List[bool]:
raise NotImplementedError()
def chunks(self) -> int:
raise NotImplementedError()
def request_chunk_from_stream(self, index: int) -> None:
raise NotImplementedError()
def should_retry(self, chunk: int) -> bool:
if self.retries[chunk] < 1:
return True
if self.retries[chunk] > self.max_chunk_tries:
return False
return self.retry_on_chunk_error
def check_availability(self, chunk: int, wait: bool, halted: bool) -> None:
if halted and not wait:
raise TypeError()
if not self.requested_chunks()[chunk]:
self.request_chunk_from_stream(chunk)
self.requested_chunks()[chunk] = True
for i in range(chunk + 1,
min(self.chunks() - 1, chunk + self.preload_ahead) + 1):
if (self.requested_chunks()[i]
and self.retries[i] < self.preload_chunk_retries):
self.request_chunk_from_stream(i)
self.requested_chunks()[chunk] = True
if wait:
if self.available_chunks()[chunk]:
return
retry = False
with self.wait_lock:
if not halted:
self.stream_read_halted(chunk, int(time.time() * 1000))
self.chunk_exception = None
self.wait_for_chunk = chunk
self.wait_lock.wait_for(lambda: self.available_chunks()[chunk])
if self.closed:
return
if self.chunk_exception is not None:
if self.should_retry(chunk):
retry = True
else:
raise AbsChunkedInputStream.ChunkException
if not retry:
self.stream_read_halted(chunk, int(time.time() * 1000))
if retry:
time.sleep(math.log10(self.retries[chunk]))
self.check_availability(chunk, True, True)
def read(self, __size: int = 0) -> bytes:
if self.closed:
raise IOError("Stream is closed!")
if __size <= 0:
if self.__pos == self.size():
return b""
buffer = io.BytesIO()
total_size = self.size()
chunk = int(self.__pos / (128 * 1024))
chunk_off = int(self.__pos % (128 * 1024))
chunk_total = int(math.ceil(total_size / (128 * 1024)))
self.check_availability(chunk, True, False)
buffer.write(self.buffer()[chunk][chunk_off:])
chunk += 1
if chunk != chunk_total:
while chunk <= chunk_total - 1:
self.check_availability(chunk, True, False)
buffer.write(self.buffer()[chunk])
chunk += 1
buffer.seek(0)
self.__pos += buffer.getbuffer().nbytes
return buffer.read()
buffer = io.BytesIO()
chunk = int(self.__pos / (128 * 1024))
chunk_off = int(self.__pos % (128 * 1024))
chunk_end = int(__size / (128 * 1024))
chunk_end_off = int(__size % (128 * 1024))
if chunk_end > self.size():
chunk_end = int(self.size() / (128 * 1024))
chunk_end_off = int(self.size() % (128 * 1024))
self.check_availability(chunk, True, False)
if chunk_off + __size > len(self.buffer()[chunk]):
buffer.write(self.buffer()[chunk][chunk_off:])
chunk += 1
while chunk <= chunk_end:
self.check_availability(chunk, True, False)
if chunk == chunk_end:
buffer.write(self.buffer()[chunk][:chunk_end_off])
else:
buffer.write(self.buffer()[chunk])
chunk += 1
else:
buffer.write(self.buffer()[chunk][chunk_off:chunk_off + __size])
buffer.seek(0)
self.__pos += buffer.getbuffer().nbytes
return buffer.read()
def notify_chunk_available(self, index: int) -> None:
self.available_chunks()[index] = True
self.__decoded_length += len(self.buffer()[index])
with self.wait_lock:
if index == self.wait_for_chunk and not self.closed:
self.wait_for_chunk = -1
self.wait_lock.notify_all()
def notify_chunk_error(self, index: int, ex):
self.available_chunks()[index] = False
self.requested_chunks()[index] = False
self.retries[index] += 1
with self.wait_lock:
if index == self.wait_for_chunk and not self.closed:
self.chunk_exception = ex
self.wait_for_chunk = -1
self.wait_lock.notify_all()
def decoded_length(self):
return self.__decoded_length
class ChunkException(IOError):
@staticmethod
def from_stream_error(stream_error: int):
return AbsChunkedInputStream \
.ChunkException("Failed due to stream error, code: {}".format(stream_error))
class AudioKeyManager(PacketsReceiver, Closeable):
audio_key_request_timeout = 20
logger = logging.getLogger("Librespot:AudioKeyManager")
__callbacks: typing.Dict[int, Callback] = {}
__seq_holder = 0
__seq_holder_lock = threading.Condition()
__session: Session
__zero_short = b"\x00\x00"
def __init__(self, session: Session):
self.__session = session
def dispatch(self, packet: Packet) -> None:
payload = io.BytesIO(packet.payload)
seq = struct.unpack(">i", payload.read(4))[0]
callback = self.__callbacks.get(seq)
if callback is None:
self.logger.warning(
"Couldn't find callback for seq: {}".format(seq))
return
if packet.is_cmd(Packet.Type.aes_key):
key = payload.read(16)
callback.key(key)
elif packet.is_cmd(Packet.Type.aes_key_error):
code = struct.unpack(">H", payload.read(2))[0]
callback.error(code)
else:
self.logger.warning(
"Couldn't handle packet, cmd: {}, length: {}".format(
packet.cmd, len(packet.payload)))
def get_audio_key(self,
gid: bytes,
file_id: bytes,
retry: bool = True) -> bytes:
seq: int
with self.__seq_holder_lock:
seq = self.__seq_holder
self.__seq_holder += 1
out = io.BytesIO()
out.write(file_id)
out.write(gid)
out.write(struct.pack(">i", seq))
out.write(self.__zero_short)
out.seek(0)
self.__session.send(Packet.Type.request_key, out.read())
callback = AudioKeyManager.SyncCallback(self)
self.__callbacks[seq] = callback
key = callback.wait_response()
if key is None:
if retry:
return self.get_audio_key(gid, file_id, False)
raise RuntimeError(
"Failed fetching audio key! gid: {}, fileId: {}".format(
util.bytes_to_hex(gid), util.bytes_to_hex(file_id)))
return key
class Callback:
def key(self, key: bytes) -> None:
raise NotImplementedError
def error(self, code: int) -> None:
raise NotImplementedError
class SyncCallback(Callback):
__audio_key_manager: AudioKeyManager
__reference = queue.Queue()
__reference_lock = threading.Condition()
def __init__(self, audio_key_manager: AudioKeyManager):
self.__audio_key_manager = audio_key_manager
def key(self, key: bytes) -> None:
with self.__reference_lock:
self.__reference.put(key)
self.__reference_lock.notify_all()
def error(self, code: int) -> None:
self.__audio_key_manager.logger.fatal(
"Audio key error, code: {}".format(code))
with self.__reference_lock:
self.__reference.put(None)
self.__reference_lock.notify_all()
def wait_response(self) -> bytes:
with self.__reference_lock:
self.__reference_lock.wait(
AudioKeyManager.audio_key_request_timeout)
return self.__reference.get(block=False)
class CdnFeedHelper:
_LOGGER: logging = logging.getLogger(__name__)
@staticmethod
def get_url(resp: StorageResolve.StorageResolveResponse) -> str:
selected_url = random.choice(resp.cdnurl)
while "audio4-gm-fb" in selected_url or "audio-gm-fb" in selected_url:
selected_url = random.choice(resp.cdnurl)
return selected_url
@staticmethod
def load_track(
session: Session, track: Metadata.Track, file: Metadata.AudioFile,
resp_or_url: typing.Union[StorageResolve.StorageResolveResponse,
str], preload: bool,
halt_listener: HaltListener) -> PlayableContentFeeder.LoadedStream:
if type(resp_or_url) is str:
url = resp_or_url
else:
url = CdnFeedHelper.get_url(resp_or_url)
start = int(time.time() * 1000)
key = session.audio_key().get_audio_key(track.gid, file.file_id)
audio_key_time = int(time.time() * 1000) - start
streamer = session.cdn().stream_file(file, key, url, halt_listener)
input_stream = streamer.stream()
normalization_data = NormalizationData.read(input_stream)
if input_stream.skip(0xA7) != 0xA7:
raise IOError("Couldn't skip 0xa7 bytes!")
return PlayableContentFeeder.LoadedStream(
track,
streamer,
normalization_data,
PlayableContentFeeder.Metrics(file.file_id, preload,
-1 if preload else audio_key_time),
)
@staticmethod
def load_episode_external(
session: Session, episode: Metadata.Episode,
halt_listener: HaltListener) -> PlayableContentFeeder.LoadedStream:
resp = session.client().head(episode.external_url)
if resp.status_code != 200:
CdnFeedHelper._LOGGER.warning("Couldn't resolve redirect!")
url = resp.url
CdnFeedHelper._LOGGER.debug("Fetched external url for {}: {}".format(
util.bytes_to_hex(episode.gid), url))
streamer = session.cdn().stream_external_episode(
episode, url, halt_listener)
return PlayableContentFeeder.LoadedStream(
episode,
streamer,
None,
PlayableContentFeeder.Metrics(None, False, -1),
)
@staticmethod
def load_episode(
session: Session,
episode: Metadata.Episode,
file: Metadata.AudioFile,
resp_or_url: typing.Union[StorageResolve.StorageResolveResponse, str],
preload: bool,
halt_listener: HaltListener,
) -> PlayableContentFeeder.LoadedStream:
if type(resp_or_url) is str:
url = resp_or_url
else:
url = CdnFeedHelper.get_url(resp_or_url)
start = int(time.time() * 1000)
key = session.audio_key().get_audio_key(episode.gid, file.file_id)
audio_key_time = int(time.time() * 1000) - start
streamer = session.cdn().stream_file(file, key, url, halt_listener)
input_stream = streamer.stream()
normalization_data = NormalizationData.read(input_stream)
if input_stream.skip(0xA7) != 0xA7:
raise IOError("Couldn't skip 0xa7 bytes!")
return PlayableContentFeeder.LoadedStream(
episode,
streamer,
normalization_data,
PlayableContentFeeder.Metrics(file.file_id, preload,
-1 if preload else audio_key_time),
)
class CdnManager:
logger: logging = logging.getLogger("Librespot:CdnManager")
__session: Session
def __init__(self, session: Session):
self.__session = session
def get_head(self, file_id: bytes):
response = self.__session.client() \
.get(self.__session.get_user_attribute("head-files-url", "https://heads-fa.spotify.com/head/{file_id}")
.replace("{file_id}", util.bytes_to_hex(file_id)))
if response.status_code != 200:
raise IOError("{}".format(response.status_code))
body = response.content
if body is None:
raise IOError("Response body is empty!")
return body
def stream_external_episode(self, episode: Metadata.Episode,
external_url: str,
halt_listener: HaltListener):
return CdnManager.Streamer(
self.__session,
StreamId(episode=episode),
SuperAudioFormat.MP3,
CdnManager.CdnUrl(self, None, external_url),
self.__session.cache(),
NoopAudioDecrypt(),
halt_listener,
)
def stream_file(self, file: Metadata.AudioFile, key: bytes, url: str,
halt_listener: HaltListener):
return CdnManager.Streamer(
self.__session,
StreamId(file=file),
SuperAudioFormat.get(file.format),
CdnManager.CdnUrl(self, file.file_id, url),
self.__session.cache(),
AesAudioDecrypt(key),
halt_listener,
)
def get_audio_url(self, file_id: bytes):
response = self.__session.api()\
.send("GET", "/storage-resolve/files/audio/interactive/{}".format(util.bytes_to_hex(file_id)), None, None)
if response.status_code != 200:
raise IOError(response.status_code)
body = response.content
if body is None:
raise IOError("Response body is empty!")
proto = StorageResolve.StorageResolveResponse()
proto.ParseFromString(body)
if proto.result == StorageResolve.StorageResolveResponse.Result.CDN:
url = random.choice(proto.cdnurl)
self.logger.debug("Fetched CDN url for {}: {}".format(
util.bytes_to_hex(file_id), url))
return url
raise CdnManager.CdnException(
"Could not retrieve CDN url! result: {}".format(proto.result))
class CdnException(Exception):
pass
class InternalResponse:
buffer: bytes
headers: typing.Dict[str, str]
def __init__(self, buffer: bytes, headers: typing.Dict[str, str]):
self.buffer = buffer
self.headers = headers
class CdnUrl:
__cdn_manager = None
__file_id: bytes
__expiration: int
url: str
def __init__(self, cdn_manager, file_id: typing.Union[bytes, None],
url: str):
self.__cdn_manager: CdnManager = cdn_manager
self.__file_id = file_id
self.set_url(url)
def url(self):
if self.__expiration == -1:
return self.url
if self.__expiration <= int(time.time() * 1000) + 5 * 60 * 1000:
self.url = self.__cdn_manager.get_audio_url(self.__file_id)
return self.url
def set_url(self, url: str):
self.url = url
if self.__file_id is not None:
token_url = urllib.parse.urlparse(url)
token_query = urllib.parse.parse_qs(token_url.query)
token_list = token_query.get("__token__")
try:
token_str = str(token_list[0])
except TypeError:
token_str = ""
expires_list = token_query.get("Expires")
try:
expires_str = str(expires_list[0])
except TypeError:
expires_str = ""
if token_str != "None" and len(token_str) != 0:
expire_at = None
split = token_str.split("~")
for s in split:
try:
i = s.index("=")
except ValueError:
continue
if s[:i] == "exp":
expire_at = int(s[i + 1:])
break
if expire_at is None:
self.__expiration = -1
self.__cdn_manager.logger.warning(
"Invalid __token__ in CDN url: {}".format(url))
return
self.__expiration = expire_at * 1000
elif expires_str != "None" and len(expires_str) != 0:
expires_at = None
expires_str = expires_str.split("~")[0]
expires_at = int(expires_str)
if expires_at is None:
self.__expiration = -1
self.__cdn_manager.logger.warning("Invalid Expires param in CDN url: {}".format(url))
return
self.__expiration = expires_at * 1000
else:
try:
i = token_url.query.index("_")
except ValueError:
self.__expiration = -1
self.__cdn_manager.logger \
.warning("Couldn't extract expiration, invalid parameter in CDN url: {}".format(url))
return
self.__expiration = int(token_url.query[:i]) * 1000
else:
self.__expiration = -1
class Streamer(GeneralAudioStream, GeneralWritableStream):
available: typing.List[bool]
buffer: typing.List[bytes]
chunks: int
executor_service = concurrent.futures.ThreadPoolExecutor()
halt_listener: HaltListener
requested: typing.List[bool]
size: int
__audio_format: SuperAudioFormat
__audio_decrypt: AudioDecrypt
__cdn_url: CdnManager.CdnUrl
__internal_stream: InternalStream
__session: Session
__stream_id: StreamId
def __init__(self, session: Session, stream_id: StreamId,
audio_format: SuperAudioFormat,
cdn_url: CdnManager.CdnUrl, cache: CacheManager,
audio_decrypt: AudioDecrypt, halt_listener: HaltListener):
self.__session = session
self.__stream_id = stream_id
self.__audio_format = audio_format
self.__audio_decrypt = audio_decrypt
self.__cdn_url = cdn_url
self.halt_listener = halt_listener
response = self.request(range_start=0,
range_end=ChannelManager.chunk_size - 1)
content_range = response.headers.get("Content-Range")
if content_range is None:
raise IOError("Missing Content-Range header!")
split = content_range.split("/")
self.size = int(split[1])
self.chunks = int(math.ceil(self.size / ChannelManager.chunk_size))
first_chunk = response.buffer
self.available = [False for _ in range(self.chunks)]
self.requested = [False for _ in range(self.chunks)]
self.buffer = [b"" for _ in range(self.chunks)]
self.__internal_stream = CdnManager.Streamer.InternalStream(
self, False)
self.requested[0] = True
self.write_chunk(first_chunk, 0, False)
def write_chunk(self, chunk: bytes, chunk_index: int,
cached: bool) -> None:
if self.__internal_stream.is_closed():
return
self.__session.logger.debug(
"Chunk {}/{} completed, cached: {}, stream: {}".format(
chunk_index + 1, self.chunks, cached, self.describe()))
self.buffer[chunk_index] = self.__audio_decrypt.decrypt_chunk(
chunk_index, chunk)
self.__internal_stream.notify_chunk_available(chunk_index)
def stream(self) -> AbsChunkedInputStream:
return self.__internal_stream
def codec(self) -> SuperAudioFormat:
return self.__audio_format
def describe(self) -> str:
if self.__stream_id.is_episode():
return "episode_gid: {}".format(
self.__stream_id.get_episode_gid())
return "file_id: {}".format(self.__stream_id.get_file_id())
def decrypt_time_ms(self) -> int:
return self.__audio_decrypt.decrypt_time_ms()
def request_chunk(self, index: int) -> None:
response = self.request(index)
self.write_chunk(response.buffer, index, False)
def request(self, chunk: int = None, range_start: int = None, range_end: int = None)\
-> CdnManager.InternalResponse:
if chunk is None and range_start is None and range_end is None:
raise TypeError()
if chunk is not None:
range_start = ChannelManager.chunk_size * chunk
range_end = (chunk + 1) * ChannelManager.chunk_size - 1
response = self.__session.client().get(
self.__cdn_url.url,
headers={
"Range": "bytes={}-{}".format(range_start, range_end)
},
)
if response.status_code != 206:
raise IOError(response.status_code)
body = response.content
if body is None:
raise IOError("Response body is empty!")
return CdnManager.InternalResponse(body, dict(response.headers))
class InternalStream(AbsChunkedInputStream):
streamer: CdnManager.Streamer
def __init__(self, streamer, retry_on_chunk_error: bool):
self.streamer: CdnManager.Streamer = streamer
super().__init__(retry_on_chunk_error)
def buffer(self) -> typing.List[bytes]:
return self.streamer.buffer
def size(self) -> int:
return self.streamer.size
def close(self) -> None:
super().close()
del self.streamer.buffer
def requested_chunks(self) -> typing.List[bool]:
return self.streamer.requested
def available_chunks(self) -> typing.List[bool]:
return self.streamer.available
def chunks(self) -> int:
return self.streamer.chunks
def request_chunk_from_stream(self, index: int) -> None:
self.streamer.executor_service \
.submit(lambda: self.streamer.request_chunk(index))
def stream_read_halted(self, chunk: int, _time: int) -> None:
if self.streamer.halt_listener is not None:
self.streamer.executor_service\
.submit(lambda: self.streamer.halt_listener.stream_read_halted(chunk, _time))
def stream_read_resumed(self, chunk: int, _time: int) -> None:
if self.streamer.halt_listener is not None:
self.streamer.executor_service \
.submit(lambda: self.streamer.halt_listener.stream_read_resumed(chunk, _time))
class NormalizationData:
_LOGGER: logging = logging.getLogger(__name__)
track_gain_db: float
track_peak: float
album_gain_db: float
album_peak: float
def __init__(self, track_gain_db: float, track_peak: float,
album_gain_db: float, album_peak: float):
self.track_gain_db = track_gain_db
self.track_peak = track_peak
self.album_gain_db = album_gain_db
self.album_peak = album_peak
self._LOGGER.debug(
"Loaded normalization data, track_gain: {}, track_peak: {}, album_gain: {}, album_peak: {}"
.format(track_gain_db, track_peak, album_gain_db, album_peak))
@staticmethod
def read(input_stream: AbsChunkedInputStream) -> NormalizationData:
input_stream.seek(144)
data = input_stream.read(4 * 4)
input_stream.seek(0)
buffer = io.BytesIO(data)
return NormalizationData(
struct.unpack("<f", buffer.read(4))[0],
struct.unpack("<f", buffer.read(4))[0],
struct.unpack("<f", buffer.read(4))[0],
struct.unpack("<f", buffer.read(4))[0])
def get_factor(self, normalisation_pregain) -> float:
normalisation_factor = float(
math.pow(10, (self.track_gain_db + normalisation_pregain) / 20))
if normalisation_factor * self.track_peak > 1:
self._LOGGER \
.warning("Reducing normalisation factor to prevent clipping. Please add negative pregain to avoid.")
normalisation_factor = 1 / self.track_peak
return normalisation_factor
class PlayableContentFeeder:
logger = logging.getLogger("Librespot:PlayableContentFeeder")
storage_resolve_interactive = "/storage-resolve/files/audio/interactive/{}"
storage_resolve_interactive_prefetch = "/storage-resolve/files/audio/interactive_prefetch/{}"
__session: Session
def __init__(self, session: Session):
self.__session = session
def load(self, playable_id: PlayableId,
audio_quality_picker: AudioQualityPicker, preload: bool,
halt_listener: typing.Union[HaltListener, None]):
if type(playable_id) is TrackId:
return self.load_track(playable_id, audio_quality_picker, preload,
halt_listener)
if type(playable_id) is EpisodeId:
return self.load_episode(playable_id, audio_quality_picker,
preload, halt_listener)
raise TypeError("Unknown content: {}".format(playable_id))
def load_stream(self, file: Metadata.AudioFile, track: Metadata.Track,
episode: Metadata.Episode, preload: bool,
halt_lister: HaltListener):
if track is None and episode is None:
raise RuntimeError()
response = self.resolve_storage_interactive(file.file_id, preload)
if response.result == StorageResolve.StorageResolveResponse.Result.CDN:
if track is not None:
return CdnFeedHelper.load_track(self.__session, track, file,
response, preload, halt_lister)
return CdnFeedHelper.load_episode(self.__session, episode, file,
response, preload, halt_lister)
if response.result == StorageResolve.StorageResolveResponse.Result.STORAGE:
if track is None:
pass
elif response.result == StorageResolve.StorageResolveResponse.Result.RESTRICTED:
raise RuntimeError("Content is restricted!")
elif response.result == StorageResolve.StorageResolveResponse.Response.UNRECOGNIZED:
raise RuntimeError("Content is unrecognized!")
else:
raise RuntimeError("Unknown result: {}".format(response.result))
def load_episode(self, episode_id: EpisodeId,
audio_quality_picker: AudioQualityPicker, preload: bool,
halt_listener: HaltListener) -> LoadedStream:
episode = self.__session.api().get_metadata_4_episode(episode_id)
if episode.external_url:
return CdnFeedHelper.load_episode_external(self.__session, episode,
halt_listener)
file = audio_quality_picker.get_file(episode.audio)
if file is None:
self.logger.fatal(
"Couldn't find any suitable audio file, available: {}".format(
episode.audio))
return self.load_stream(file, None, episode, preload, halt_listener)
def load_track(self, track_id_or_track: typing.Union[TrackId,
Metadata.Track],
audio_quality_picker: AudioQualityPicker, preload: bool,
halt_listener: HaltListener):
if type(track_id_or_track) is TrackId:
original = self.__session.api().get_metadata_4_track(
track_id_or_track)
track = self.pick_alternative_if_necessary(original)
if track is None:
raise RuntimeError("Cannot get alternative track")
else:
track = track_id_or_track
file = audio_quality_picker.get_file(track.file)
if file is None:
self.logger.fatal(
"Couldn't find any suitable audio file, available: {}".format(
track.file))
raise FeederException()
return self.load_stream(file, track, None, preload, halt_listener)
def pick_alternative_if_necessary(
self, track: Metadata.Track) -> typing.Union[Metadata.Track, None]:
if len(track.file) > 0:
return track
for alt in track.alternative:
if len(alt.file) > 0:
return Metadata.Track(
gid=track.gid,
name=track.name,
album=track.album,
artist=track.artist,
number=track.number,
disc_number=track.disc_number,
duration=track.duration,
popularity=track.popularity,
explicit=track.explicit,
external_id=track.external_id,
restriction=track.restriction,
file=alt.file,
sale_period=track.sale_period,
preview=track.preview,
tags=track.tags,
earliest_live_timestamp=track.earliest_live_timestamp,
has_lyrics=track.has_lyrics,
availability=track.availability,
licensor=track.licensor)
return None
def resolve_storage_interactive(
self, file_id: bytes,
preload: bool) -> StorageResolve.StorageResolveResponse:
resp = self.__session.api().send(
"GET",
(self.storage_resolve_interactive_prefetch
if preload else self.storage_resolve_interactive).format(
util.bytes_to_hex(file_id)),
None,
None,
)
if resp.status_code != 200:
raise RuntimeError(resp.status_code)
body = resp.content
if body is None:
raise RuntimeError("Response body is empty!")
storage_resolve_response = StorageResolve.StorageResolveResponse()
storage_resolve_response.ParseFromString(body)
return storage_resolve_response
class LoadedStream:
episode: Metadata.Episode
track: Metadata.Track
input_stream: GeneralAudioStream
normalization_data: NormalizationData
metrics: PlayableContentFeeder.Metrics
def __init__(self, track_or_episode: typing.Union[Metadata.Track,
Metadata.Episode],
input_stream: GeneralAudioStream,
normalization_data: typing.Union[NormalizationData, None],
metrics: PlayableContentFeeder.Metrics):
if type(track_or_episode) is Metadata.Track:
self.track = track_or_episode
self.episode = None
elif type(track_or_episode) is Metadata.Episode:
self.track = None
self.episode = track_or_episode
else:
raise TypeError()
self.input_stream = input_stream
self.normalization_data = normalization_data
self.metrics = metrics
class Metrics:
file_id: str
preloaded_audio_key: bool
audio_key_time: int
def __init__(self, file_id: typing.Union[bytes, None],
preloaded_audio_key: bool, audio_key_time: int):
self.file_id = None if file_id is None else util.bytes_to_hex(
file_id)
self.preloaded_audio_key = preloaded_audio_key
self.audio_key_time = audio_key_time
if preloaded_audio_key and audio_key_time != -1:
raise RuntimeError()
class StreamId:
file_id: bytes
episode_gid: bytes
def __init__(self,
file: Metadata.AudioFile = None,
episode: Metadata.Episode = None):
if file is None and episode is None:
return
self.file_id = None if file is None else file.file_id
self.episode_gid = None if episode is None else episode.gid
def get_file_id(self):
if self.file_id is None:
raise RuntimeError("Not a file!")
return util.bytes_to_hex(self.file_id)
def is_episode(self):
return self.episode_gid is not None
def get_episode_gid(self):
if self.episode_gid is None:
raise RuntimeError("Not an episode!")
return util.bytes_to_hex(self.episode_gid)

View file

@ -0,0 +1,81 @@
from __future__ import annotations
from librespot.audio import SuperAudioFormat
from librespot.proto import Metadata_pb2 as Metadata
from librespot.proto.Metadata_pb2 import AudioFile
from librespot.structure import AudioQualityPicker
import enum
import logging
import typing
class AudioQuality(enum.Enum):
NORMAL = 0x00
HIGH = 0x01
VERY_HIGH = 0x02
@staticmethod
def get_quality(audio_format: AudioFile.Format) -> AudioQuality:
if audio_format in [
AudioFile.MP3_96,
AudioFile.OGG_VORBIS_96,
AudioFile.AAC_24_NORM,
]:
return AudioQuality.NORMAL
if audio_format in [
AudioFile.MP3_160,
AudioFile.MP3_160_ENC,
AudioFile.OGG_VORBIS_160,
AudioFile.AAC_24,
]:
return AudioQuality.HIGH
if audio_format in [
AudioFile.MP3_320,
AudioFile.MP3_256,
AudioFile.OGG_VORBIS_320,
AudioFile.AAC_48,
]:
return AudioQuality.VERY_HIGH
raise RuntimeError("Unknown format: {}".format(format))
def get_matches(self,
files: typing.List[AudioFile]) -> typing.List[AudioFile]:
file_list = []
for file in files:
if hasattr(file, "format") and AudioQuality.get_quality(
file.format) == self:
file_list.append(file)
return file_list
class VorbisOnlyAudioQuality(AudioQualityPicker):
logger = logging.getLogger("Librespot:Player:VorbisOnlyAudioQuality")
preferred: AudioQuality
def __init__(self, preferred: AudioQuality):
self.preferred = preferred
@staticmethod
def get_vorbis_file(files: typing.List[Metadata.AudioFile]):
for file in files:
if file.HasField("format") and SuperAudioFormat.get(
file.format) == SuperAudioFormat.VORBIS:
return file
return None
def get_file(self, files: typing.List[Metadata.AudioFile]):
matches: typing.List[Metadata.AudioFile] = self.preferred.get_matches(
files)
vorbis: Metadata.AudioFile = VorbisOnlyAudioQuality.get_vorbis_file(
matches)
if vorbis is None:
vorbis: Metadata.AudioFile = VorbisOnlyAudioQuality.get_vorbis_file(
files)
if vorbis is not None:
self.logger.warning(
"Using {} because preferred {} couldn't be found.".format(
Metadata.AudioFile.Format.Name(vorbis.format),
self.preferred))
else:
self.logger.fatal(
"Couldn't find any Vorbis file, available: {}")
return vorbis

View file

@ -0,0 +1,45 @@
from __future__ import annotations
from Cryptodome.Cipher import AES
from Cryptodome.Util import Counter
from librespot.audio.storage import ChannelManager
from librespot.structure import AudioDecrypt
import io
import time
class AesAudioDecrypt(AudioDecrypt):
audio_aes_iv = b'r\xe0g\xfb\xdd\xcb\xcfw\xeb\xe8\xbcd?c\r\x93'
cipher = None
decrypt_count = 0
decrypt_total_time = 0
iv_int = int.from_bytes(audio_aes_iv, "big")
iv_diff = 0x100
key: bytes
def __init__(self, key: bytes):
self.key = key
def decrypt_chunk(self, chunk_index: int, buffer: bytes):
new_buffer = io.BytesIO()
iv = self.iv_int + int(ChannelManager.chunk_size * chunk_index / 16)
start = time.time_ns()
for i in range(0, len(buffer), 4096):
cipher = AES.new(key=self.key,
mode=AES.MODE_CTR,
counter=Counter.new(128, initial_value=iv))
count = min(4096, len(buffer) - i)
decrypted_buffer = cipher.decrypt(buffer[i:i + count])
new_buffer.write(decrypted_buffer)
if count != len(decrypted_buffer):
raise RuntimeError(
"Couldn't process all data, actual: {}, expected: {}".
format(len(decrypted_buffer), count))
iv += self.iv_diff
self.decrypt_total_time += time.time_ns() - start
self.decrypt_count += 1
new_buffer.seek(0)
return new_buffer.read()
def decrypt_time_ms(self):
return 0 if self.decrypt_count == 0 else int(
(self.decrypt_total_time / self.decrypt_count) / 1000000)

View file

@ -0,0 +1,32 @@
from librespot.proto import Metadata_pb2 as Metadata
import enum
class SuperAudioFormat(enum.Enum):
MP3 = 0x00
VORBIS = 0x01
AAC = 0x02
@staticmethod
def get(audio_format: Metadata.AudioFile.Format):
if audio_format in [
Metadata.AudioFile.Format.OGG_VORBIS_96,
Metadata.AudioFile.Format.OGG_VORBIS_160,
Metadata.AudioFile.Format.OGG_VORBIS_320,
]:
return SuperAudioFormat.VORBIS
if audio_format in [
Metadata.AudioFile.Format.MP3_256,
Metadata.AudioFile.Format.MP3_320,
Metadata.AudioFile.Format.MP3_160,
Metadata.AudioFile.Format.MP3_96,
Metadata.AudioFile.Format.MP3_160_ENC,
]:
return SuperAudioFormat.MP3
if audio_format in [
Metadata.AudioFile.Format.AAC_24,
Metadata.AudioFile.Format.AAC_48,
Metadata.AudioFile.Format.AAC_24_NORM,
]:
return SuperAudioFormat.AAC
raise RuntimeError("Unknown audio format: {}".format(audio_format))

View file

@ -0,0 +1,139 @@
from __future__ import annotations
from librespot import util
from librespot.crypto import Packet
from librespot.proto.Metadata_pb2 import AudioFile
from librespot.structure import Closeable, PacketsReceiver
import concurrent.futures
import io
import logging
import queue
import struct
import threading
import typing
if typing.TYPE_CHECKING:
from librespot.core import Session
class ChannelManager(Closeable, PacketsReceiver):
channels: typing.Dict[int, Channel] = {}
chunk_size = 128 * 1024
executor_service = concurrent.futures.ThreadPoolExecutor()
logger = logging.getLogger("Librespot:ChannelManager")
seq_holder = 0
seq_holder_lock = threading.Condition()
__session: Session = None
def __init__(self, session: Session):
self.__session = session
def request_chunk(self, file_id: bytes, index: int, file: AudioFile):
start = int(index * self.chunk_size / 4)
end = int((index + 1) * self.chunk_size / 4)
channel = ChannelManager.Channel(self, file, index)
self.channels[channel.chunk_id] = channel
out = io.BytesIO()
out.write(struct.pack(">H", channel.chunk_id))
out.write(struct.pack(">i", 0x00000000))
out.write(struct.pack(">i", 0x00000000))
out.write(struct.pack(">i", 0x00004E20))
out.write(struct.pack(">i", 0x00030D40))
out.write(file_id)
out.write(struct.pack(">i", start))
out.write(struct.pack(">i", end))
out.seek(0)
self.__session.send(Packet.Type.stream_chunk, out.read())
def dispatch(self, packet: Packet) -> None:
payload = io.BytesIO(packet.payload)
if packet.is_cmd(Packet.Type.stream_chunk_res):
chunk_id = struct.unpack(">H", payload.read(2))[0]
channel = self.channels.get(chunk_id)
if channel is None:
self.logger.warning(
"Couldn't find channel, id: {}, received: {}".format(
chunk_id, len(packet.payload)))
return
channel.add_to_queue(payload)
elif packet.is_cmd(Packet.Type.channel_error):
chunk_id = struct.unpack(">H", payload.read(2))[0]
channel = self.channels.get(chunk_id)
if channel is None:
self.logger.warning(
"Dropping channel error, id: {}, code: {}".format(
chunk_id,
struct.unpack(">H", payload.read(2))[0]))
return
channel.stream_error(struct.unpack(">H", payload.read(2))[0])
else:
self.logger.warning(
"Couldn't handle packet, cmd: {}, payload: {}".format(
packet.cmd, util.bytes_to_hex(packet.payload)))
def close(self) -> None:
self.executor_service.shutdown()
class Channel:
channel_manager: ChannelManager
chunk_id: int
q = queue.Queue()
__buffer: io.BytesIO
__chunk_index: int
__file: AudioFile
__header: bool = True
def __init__(self, channel_manager: ChannelManager, file: AudioFile,
chunk_index: int):
self.__buffer = io.BytesIO()
self.channel_manager = channel_manager
self.__file = file
self.__chunk_index = chunk_index
with self.channel_manager.seq_holder_lock:
self.chunk_id = self.channel_manager.seq_holder
self.channel_manager.seq_holder += 1
self.channel_manager.executor_service.submit(
lambda: ChannelManager.Channel.Handler(self))
def _handle(self, payload: bytes) -> bool:
if len(payload) == 0:
if not self.__header:
self.__file.write_chunk(payload, self.__chunk_index, False)
return True
self.channel_manager.logger.debug(
"Received empty chunk, skipping.")
return False
if self.__header:
length: int
while len(payload.buffer) > 0:
length = payload.read_short()
if not length > 0:
break
header_id = payload.read_byte()
header_data = payload.read(length - 1)
self.__file.write_header(int.from_bytes(header_id, "big"),
bytearray(header_data), False)
self.__header = False
else:
self.__buffer.write(payload.read(len(payload.buffer)))
return False
def add_to_queue(self, payload):
self.q.put(payload)
def stream_error(self, code: int) -> None:
self.__file.stream_error(self.__chunk_index, code)
class Handler:
__channel: ChannelManager.Channel = None
def __init__(self, channel: ChannelManager.Channel):
self.__channel = channel
def run(self) -> None:
self.__channel.channel_manager.logger.debug(
"ChannelManager.Handler is starting")
with self.__channel.q.all_tasks_done:
self.__channel.channel_manager.channels.pop(
self.__channel.chunk_id)
self.__channel.channel_manager.logger.debug(
"ChannelManager.Handler is shutting down")

View file

@ -0,0 +1,18 @@
from __future__ import annotations
import typing
if typing.TYPE_CHECKING:
from librespot.core import Session
class CacheManager:
clean_up_threshold = 604800000
header_hash = 253
header_timestamp = 254
parent: str
def __init__(self, session: Session):
"""
@Todo Implement function
:param session:
"""

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,412 @@
from __future__ import annotations
from Cryptodome import Random
from librespot import util
import io
import re
import struct
import typing
if typing.TYPE_CHECKING:
from librespot.core import Session
class CipherPair:
__receive_cipher: Shannon
__receive_nonce = 0
__send_cipher: Shannon
__send_nonce = 0
def __init__(self, send_key: bytes, receive_key: bytes):
self.__send_cipher = Shannon()
self.__send_cipher.key(send_key)
self.__receive_cipher = Shannon()
self.__receive_cipher.key(receive_key)
def send_encoded(self, connection: Session.ConnectionHolder, cmd: bytes,
payload: bytes) -> None:
"""
Send decrypted data to the socket
:param connection:
:param cmd:
:param payload:
:return:
"""
self.__send_cipher.nonce(self.__send_nonce)
self.__send_nonce += 1
buffer = io.BytesIO()
buffer.write(cmd)
buffer.write(struct.pack(">H", len(payload)))
buffer.write(payload)
buffer.seek(0)
contents = self.__send_cipher.encrypt(buffer.read())
mac = self.__send_cipher.finish(4)
connection.write(contents)
connection.write(mac)
connection.flush()
def receive_encoded(self, connection: Session.ConnectionHolder) -> Packet:
"""
Receive and parse decrypted data from the socket
Args:
connection: ConnectionHolder
Return:
The parsed packet will be returned
"""
try:
self.__receive_cipher.nonce(self.__receive_nonce)
self.__receive_nonce += 1
header_bytes = self.__receive_cipher.decrypt(connection.read(3))
cmd = struct.pack(">s", bytes([header_bytes[0]]))
payload_length = (header_bytes[1] << 8) | (header_bytes[2] & 0xff)
payload_bytes = self.__receive_cipher.decrypt(
connection.read(payload_length))
mac = connection.read(4)
expected_mac = self.__receive_cipher.finish(4)
if mac != expected_mac:
raise RuntimeError()
return Packet(cmd, payload_bytes)
except IndexError:
raise RuntimeError("Failed to receive packet")
class DiffieHellman:
"""
DiffieHellman Keyexchange
"""
__prime = int.from_bytes(
b'\xff\xff\xff\xff\xff\xff\xff\xff\xc9\x0f'
b'\xda\xa2!h\xc24\xc4\xc6b\x8b\x80\xdc\x1c'
b'\xd1)\x02N\x08\x8ag\xcct\x02\x0b\xbe\xa6;'
b'\x13\x9b"QJ\x08y\x8e4\x04\xdd\xef\x95\x19'
b'\xb3\xcd:C\x1b0+\nm\xf2_\x147O\xe15mmQ\xc2'
b'E\xe4\x85\xb5vb^~\xc6\xf4LB\xe9\xa6:6 \xff'
b'\xff\xff\xff\xff\xff\xff\xff',
byteorder="big")
__private_key: int
__public_key: int
def __init__(self):
key_data = Random.get_random_bytes(0x5f)
self.__private_key = int.from_bytes(key_data, byteorder="big")
self.__public_key = pow(2, self.__private_key, self.__prime)
def compute_shared_key(self, remote_key_bytes: bytes):
"""
Compute shared_key
"""
remote_key = int.from_bytes(remote_key_bytes, "big")
return pow(remote_key, self.__private_key, self.__prime)
def private_key(self) -> int:
"""
Return DiffieHellman's private key
Returns:
DiffieHellman's private key
"""
return self.__private_key
def public_key(self) -> int:
"""
Return DiffieHellman's public key
Returns:
DiffieHellman's public key
"""
return self.__public_key
def public_key_bytes(self) -> bytes:
"""
Return DiffieHellman's packed public key
Returns:
DiffieHellman's packed public key
"""
return util.int_to_bytes(self.__public_key)
class Packet:
cmd: bytes
payload: bytes
def __init__(self, cmd: bytes, payload: bytes):
self.cmd = cmd
self.payload = payload
def is_cmd(self, cmd: bytes) -> bool:
return cmd == self.cmd
class Type:
secret_block = b"\x02"
ping = b"\x04"
stream_chunk = b"\x08"
stream_chunk_res = b"\x09"
channel_error = b"\x0a"
channel_abort = b"\x0b"
request_key = b"\x0c"
aes_key = b"\x0d"
aes_key_error = b"\x0e"
image = b"\x19"
country_code = b"\x1b"
pong = b"\x49"
pong_ack = b"\x4a"
pause = b"\x4b"
product_info = b"\x50"
legacy_welcome = b"\x69"
license_version = b"\x76"
login = b"\xab"
ap_welcome = b"\xac"
auth_failure = b"\xad"
mercury_req = b"\xb2"
mercury_sub = b"\xb3"
mercury_unsub = b"\xb4"
mercury_event = b"\xb5"
track_ended_time = b"\x82"
unknown_data_all_zeros = b"\x1f"
preferred_locale = b"\x74"
unknown_0x4f = b"\x4f"
unknown_0x0f = b"\x0f"
unknown_0x10 = b"\x10"
@staticmethod
def parse(val: typing.Union[bytes, None]) -> typing.Union[bytes, None]:
for cmd in [
Packet.Type.__dict__[attr] for attr in Packet.Type.__dict__
if re.search("__.+?__", attr) is None
and type(Packet.Type.__dict__[attr]) is bytes
]:
if cmd == val:
return cmd
return None
@staticmethod
def for_method(method: str) -> bytes:
if method == "SUB":
return Packet.Type.mercury_sub
if method == "UNSUB":
return Packet.Type.mercury_unsub
return Packet.Type.mercury_req
class Shannon:
n = 16
fold = n
initkonst = 0x6996c53a
keyp = 13
r: list
crc: list
init_r: list
konst: int
sbuf: int
mbuf: int
nbuf: int
def __init__(self):
self.r = [0 for _ in range(self.n)]
self.crc = [0 for _ in range(self.n)]
self.init_r = [0 for _ in range(self.n)]
def rotl(self, i: int, distance: int) -> int:
return ((i << distance) | (i >> (32 - distance))) & 0xffffffff
def sbox(self, i: int) -> int:
i ^= self.rotl(i, 5) | self.rotl(i, 7)
i ^= self.rotl(i, 19) | self.rotl(i, 22)
return i
def sbox2(self, i: int) -> int:
i ^= self.rotl(i, 7) | self.rotl(i, 22)
i ^= self.rotl(i, 5) | self.rotl(i, 19)
return i
def cycle(self) -> None:
t: int
t = self.r[12] ^ self.r[13] ^ self.konst
t = self.sbox(t) ^ self.rotl(self.r[0], 1)
for i in range(1, self.n):
self.r[i - 1] = self.r[i]
self.r[self.n - 1] = t
t = self.sbox2(self.r[2] ^ self.r[15])
self.r[0] ^= t
self.sbuf = t ^ self.r[8] ^ self.r[12]
def crc_func(self, i: int) -> None:
t: int
t = self.crc[0] ^ self.crc[2] ^ self.crc[15] ^ i
for j in range(1, self.n):
self.crc[j - 1] = self.crc[j]
self.crc[self.n - 1] = t
def mac_func(self, i: int) -> None:
self.crc_func(i)
self.r[self.keyp] ^= i
def init_state(self) -> None:
self.r[0] = 1
self.r[1] = 1
for i in range(2, self.n):
self.r[i] = self.r[i - 1] + self.r[i - 2]
self.konst = self.initkonst
def save_state(self) -> None:
for i in range(self.n):
self.init_r[i] = self.r[i]
def reload_state(self) -> None:
for i in range(self.n):
self.r[i] = self.init_r[i]
def gen_konst(self) -> None:
self.konst = self.r[0]
def add_key(self, k: int) -> None:
self.r[self.keyp] ^= k
def diffuse(self) -> None:
for _ in range(self.fold):
self.cycle()
def load_key(self, key: bytes) -> None:
i: int
j: int
t: int
padding_size = int((len(key) + 3) / 4) * 4 - len(key)
key = key + (b"\x00" * padding_size) + struct.pack("<I", len(key))
for i in range(0, len(key), 4):
self.r[self.keyp] = \
self.r[self.keyp] ^ \
struct.unpack("<I", key[i: i + 4])[0]
self.cycle()
for i in range(self.n):
self.crc[i] = self.r[i]
self.diffuse()
for i in range(self.n):
self.r[i] ^= self.crc[i]
def key(self, key: bytes) -> None:
self.init_state()
self.load_key(key)
self.gen_konst()
self.save_state()
self.nbuf = 0
def nonce(self, nonce: typing.Union[bytes, int]) -> None:
if type(nonce) is int:
nonce = bytes(struct.pack(">I", nonce))
self.reload_state()
self.konst = self.initkonst
self.load_key(nonce)
self.gen_konst()
self.nbuf = 0
def encrypt(self, buffer: bytes, n: int = None) -> bytes:
if n is None:
return self.encrypt(buffer, len(buffer))
buffer = bytearray(buffer)
i = 0
j: int
t: int
if self.nbuf != 0:
while self.nbuf != 0 and n != 0:
self.mbuf ^= (buffer[i] & 0xff) << (32 - self.nbuf)
buffer[i] ^= (self.sbuf >> (32 - self.nbuf)) & 0xff
i += 1
self.nbuf -= 8
n -= 1
if self.nbuf != 0:
return b""
self.mac_func(self.mbuf)
j = n & ~0x03
while i < j:
self.cycle()
t = ((buffer[i + 3] & 0xFF) << 24) | \
((buffer[i + 2] & 0xFF) << 16) | \
((buffer[i + 1] & 0xFF) << 8) | \
(buffer[i] & 0xFF)
self.mac_func(t)
t ^= self.sbuf
buffer[i + 3] = (t >> 24) & 0xFF
buffer[i + 2] = (t >> 16) & 0xFF
buffer[i + 1] = (t >> 8) & 0xFF
buffer[i] = t & 0xFF
i += 4
n &= 0x03
if n != 0:
self.cycle()
self.mbuf = 0
self.nbuf = 32
while self.nbuf != 0 and n != 0:
self.mbuf ^= (buffer[i] & 0xff) << (32 - self.nbuf)
buffer[i] ^= (self.sbuf >> (32 - self.nbuf)) & 0xff
i += 1
self.nbuf -= 8
n -= 1
return bytes(buffer)
def decrypt(self, buffer: bytes, n: int = None) -> bytes:
if n is None:
return self.decrypt(buffer, len(buffer))
buffer = bytearray(buffer)
i = 0
j: int
t: int
if self.nbuf != 0:
while self.nbuf != 0 and n != 0:
buffer[i] ^= (self.sbuf >> (32 - self.nbuf)) & 0xff
self.mbuf ^= (buffer[i] & 0xff) << (32 - self.nbuf)
i += 1
self.nbuf -= 8
n -= 1
if self.nbuf != 0:
return b""
self.mac_func(self.mbuf)
j = n & ~0x03
while i < j:
self.cycle()
t = ((buffer[i + 3] & 0xFF) << 24) | \
((buffer[i + 2] & 0xFF) << 16) | \
((buffer[i + 1] & 0xFF) << 8) | \
(buffer[i] & 0xFF)
t ^= self.sbuf
self.mac_func(t)
buffer[i + 3] = (t >> 24) & 0xFF
buffer[i + 2] = (t >> 16) & 0xFF
buffer[i + 1] = (t >> 8) & 0xFF
buffer[i] = t & 0xFF
i += 4
n &= 0x03
if n != 0:
self.cycle()
self.mbuf = 0
self.nbuf = 32
while self.nbuf != 0 and n != 0:
buffer[i] ^= (self.sbuf >> (32 - self.nbuf)) & 0xff
self.mbuf ^= (buffer[i] & 0xff) << (32 - self.nbuf)
i += 1
self.nbuf -= 8
n -= 1
return bytes(buffer)
def finish(self, n: int) -> bytes:
buffer = bytearray(4)
i = 0
j: int
if self.nbuf != 0:
self.mac_func(self.mbuf)
self.cycle()
self.add_key(self.initkonst ^ (self.nbuf << 3))
self.nbuf = 0
for j in range(self.n):
self.r[j] ^= self.crc[j]
self.diffuse()
while n > 0:
self.cycle()
if n >= 4:
buffer[i + 3] = (self.sbuf >> 24) & 0xff
buffer[i + 2] = (self.sbuf >> 16) & 0xff
buffer[i + 1] = (self.sbuf >> 8) & 0xff
buffer[i] = self.sbuf & 0xff
n -= 4
i += 4
else:
for j in range(n):
buffer[i + j] = (self.sbuf >> (i * 8)) & 0xff
break
return bytes(buffer)

View file

@ -0,0 +1,11 @@
from __future__ import annotations
from librespot.core import ApResolver
from librespot.metadata import AlbumId, ArtistId, EpisodeId, ShowId, TrackId
from librespot.proto import Connect_pb2 as Connect, Metadata_pb2 as Metadata
from librespot.structure import Closeable
import logging
import requests
import typing
if typing.TYPE_CHECKING:
from librespot.core import Session

View file

@ -0,0 +1,394 @@
from __future__ import annotations
from librespot import util
from librespot.crypto import Packet
from librespot.proto import Mercury_pb2 as Mercury, Pubsub_pb2 as Pubsub
from librespot.structure import Closeable, PacketsReceiver, SubListener
import io
import json
import logging
import queue
import struct
import threading
import typing
if typing.TYPE_CHECKING:
from librespot.core import Session
class JsonMercuryRequest:
request: RawMercuryRequest
def __init__(self, request: RawMercuryRequest):
self.request = request
class MercuryClient(Closeable, PacketsReceiver):
logger = logging.getLogger("Librespot:MercuryClient")
mercury_request_timeout = 3
__callbacks: typing.Dict[int, Callback] = {}
__remove_callback_lock = threading.Condition()
__partials: typing.Dict[int, typing.List[bytes]] = {}
__seq_holder = 0
__seq_holder_lock = threading.Condition()
__session: Session
__subscriptions: typing.List[InternalSubListener] = []
__subscriptions_lock = threading.Condition()
def __init__(self, session: Session):
self.__session = session
def close(self) -> None:
"""
Close the MercuryClient instance
"""
if len(self.__subscriptions) != 0:
for listener in self.__subscriptions:
if listener.is_sub:
self.unsubscribe(listener.uri)
else:
self.not_interested_in(listener.listener)
if len(self.__callbacks) != 0:
with self.__remove_callback_lock:
self.__remove_callback_lock.wait(self.mercury_request_timeout)
self.__callbacks.clear()
def dispatch(self, packet: Packet) -> None:
payload = io.BytesIO(packet.payload)
seq_length = struct.unpack(">H", payload.read(2))[0]
if seq_length == 2:
seq = struct.unpack(">H", payload.read(2))[0]
elif seq_length == 4:
seq = struct.unpack(">i", payload.read(4))[0]
elif seq_length == 8:
seq = struct.unpack(">q", payload.read(8))[0]
else:
raise RuntimeError("Unknown seq length: {}".format(seq_length))
flags = payload.read(1)
parts = struct.unpack(">H", payload.read(2))[0]
partial = self.__partials.get(seq)
if partial is None or flags == 0:
partial = []
self.__partials[seq] = partial
self.logger.debug(
"Handling packet, cmd: 0x{}, seq: {}, flags: {}, parts: {}".format(
util.bytes_to_hex(packet.cmd), seq, flags, parts))
for _ in range(parts):
size = struct.unpack(">H", payload.read(2))[0]
buffer = payload.read(size)
partial.append(buffer)
self.__partials[seq] = partial
if flags != b"\x01":
return
self.__partials.pop(seq)
header = Mercury.Header()
header.ParseFromString(partial[0])
response = MercuryClient.Response(header, partial)
if packet.is_cmd(Packet.Type.mercury_event):
dispatched = False
with self.__subscriptions_lock:
for sub in self.__subscriptions:
if sub.matches(header.uri):
sub.dispatch(response)
dispatched = True
if not dispatched:
self.logger.debug(
"Couldn't dispatch Mercury event seq: {}, uri: {}, code: {}, payload: {}"
.format(seq, header.uri, header.status_code,
response.payload))
elif (packet.is_cmd(Packet.Type.mercury_req)
or packet.is_cmd(Packet.Type.mercury_sub)
or packet.is_cmd(Packet.Type.mercury_sub)):
callback = self.__callbacks.get(seq)
self.__callbacks.pop(seq)
if callback is not None:
callback.response(response)
else:
self.logger.warning(
"Skipped Mercury response, seq: {}, uri: {}, code: {}".
format(seq, response.uri, response.status_code))
with self.__remove_callback_lock:
self.__remove_callback_lock.notify_all()
else:
self.logger.warning(
"Couldn't handle packet, seq: {}, uri: {}, code: {}".format(
seq, header.uri, header.status_code))
def interested_in(self, uri: str, listener: SubListener) -> None:
self.__subscriptions.append(
MercuryClient.InternalSubListener(uri, listener, False))
def not_interested_in(self, listener: SubListener) -> None:
try:
for subscription in self.__subscriptions:
if subscription.listener is listener:
self.__subscriptions.remove(subscription)
break
except ValueError:
pass
def send(self, request: RawMercuryRequest, callback) -> int:
"""
Send the Mercury request
Args:
request: RawMercuryRequest
callback: Callback function
Returns:
MercuryClient.Response
"""
buffer = io.BytesIO()
seq: int
with self.__seq_holder_lock:
seq = self.__seq_holder
self.__seq_holder += 1
self.logger.debug(
"Send Mercury request, seq: {}, uri: {}, method: {}".format(
seq, request.header.uri, request.header.method))
buffer.write(struct.pack(">H", 4))
buffer.write(struct.pack(">i", seq))
buffer.write(b"\x01")
buffer.write(struct.pack(">H", 1 + len(request.payload)))
header_bytes = request.header.SerializeToString()
buffer.write(struct.pack(">H", len(header_bytes)))
buffer.write(header_bytes)
for part in request.payload:
buffer.write(struct.pack(">H", len(part)))
buffer.write(part)
buffer.seek(0)
cmd = Packet.Type.for_method(request.header.method)
self.__session.send(cmd, buffer.read())
self.__callbacks[seq] = callback
return seq
def send_sync(self, request: RawMercuryRequest) -> Response:
"""
Send the Mercury request
Args:
request: RawMercuryRequest
Returns:
MercuryClient.Response
"""
callback = MercuryClient.SyncCallback()
seq = self.send(request, callback)
try:
response = callback.wait_response()
if response is None:
raise IOError(
"Request timeout out, {} passed, yet no response. seq: {}".
format(self.mercury_request_timeout, seq))
return response
except queue.Empty as e:
raise IOError(e)
def send_sync_json(self, request: JsonMercuryRequest) -> typing.Any:
response = self.send_sync(request.request)
if 200 <= response.status_code < 300:
return json.loads(response.payload)
raise MercuryClient.MercuryException(response)
def subscribe(self, uri: str, listener: SubListener) -> None:
"""
Subscribe URI
Args:
uri:
listener:
"""
response = self.send_sync(RawMercuryRequest.sub(uri))
if response.status_code != 200:
raise RuntimeError(response)
if len(response.payload) > 0:
for payload in response.payload:
sub = Pubsub.Subscription()
sub.ParseFromString(payload)
self.__subscriptions.append(
MercuryClient.InternalSubListener(sub.uri, listener, True))
else:
self.__subscriptions.append(
MercuryClient.InternalSubListener(uri, listener, True))
self.logger.debug("Subscribed successfully to {}!".format(uri))
def unsubscribe(self, uri) -> None:
"""
Unsubscribe URI
Args:
uri:
"""
response = self.send_sync(RawMercuryRequest.unsub(uri))
if response.status_code != 200:
raise RuntimeError(response)
for subscription in self.__subscriptions:
if subscription.matches(uri):
self.__subscriptions.remove(subscription)
break
self.logger.debug("Unsubscribed successfully from {}!".format(uri))
class Callback:
def response(self, response: MercuryClient.Response) -> None:
raise NotImplementedError
class InternalSubListener:
uri: str
listener: SubListener
is_sub: bool
def __init__(self, uri: str, listener: SubListener, is_sub: bool):
self.uri = uri
self.listener = listener
self.is_sub = is_sub
def matches(self, uri: str) -> bool:
"""
Compare with the URI given
Args:
uri: URI to be compared
Returns:
bool
"""
return uri.startswith(self.uri)
def dispatch(self, response: MercuryClient.Response) -> None:
"""
Dispatch the event response
Args:
response: Response generated by the event
"""
self.listener.event(response)
class MercuryException(Exception):
code: int
def __init__(self, response: MercuryClient.Response):
super().__init__("status: {}".format(response.status_code))
self.code = response.status_code
class PubSubException(MercuryException):
pass
class Response:
uri: str
payload: bytes
status_code: int
def __init__(self, header: Mercury.Header, payload: list[bytes]):
self.uri = header.uri
self.status_code = header.status_code
self.payload = b"".join(payload[1:])
class SyncCallback(Callback):
__reference = queue.Queue()
def response(self, response: MercuryClient.Response) -> None:
"""
Set the response
:param response:
:return:
"""
self.__reference.put(response)
self.__reference.task_done()
def wait_response(self) -> typing.Any:
return self.__reference.get(
timeout=MercuryClient.mercury_request_timeout)
class MercuryRequests:
keymaster_client_id = "65b708073fc0480ea92a077233ca87bd"
@staticmethod
def get_root_playlists(username: str):
"""
@TODO implement function
"""
@staticmethod
def request_token(device_id, scope):
return JsonMercuryRequest(
RawMercuryRequest.get(
"hm://keymaster/token/authenticated?scope={}&client_id={}&device_id={}"
.format(scope, MercuryRequests.keymaster_client_id,
device_id)))
class RawMercuryRequest:
header: Mercury.Header
payload: typing.List[bytes]
def __init__(self, header: Mercury.Header, payload: typing.List[bytes]):
self.header = header
self.payload = payload
@staticmethod
def sub(uri: str):
return RawMercuryRequest.new_builder().set_uri(uri).set_method(
"SUB").build()
@staticmethod
def unsub(uri: str):
return RawMercuryRequest.new_builder().set_uri(uri).set_method(
"UNSUB").build()
@staticmethod
def get(uri: str):
return RawMercuryRequest.new_builder().set_uri(uri).set_method(
"GET").build()
@staticmethod
def send(uri: str, part: bytes):
return RawMercuryRequest.new_builder().set_uri(uri) \
.add_payload_part(part).set_method("SEND").build()
@staticmethod
def post(uri: str, part: bytes):
return RawMercuryRequest.new_builder().set_uri(uri) \
.set_method("POST").add_payload_part(part).build()
@staticmethod
def new_builder():
return RawMercuryRequest.Builder()
class Builder:
header_dict: dict
payload: typing.List[bytes]
def __init__(self):
self.header_dict = {}
self.payload = []
def set_uri(self, uri: str):
self.header_dict["uri"] = uri
return self
def set_content_type(self, content_type: str):
self.header_dict["content_type"] = content_type
return self
def set_method(self, method: str):
self.header_dict["method"] = method
return self
def add_user_field(self,
field: Mercury.UserField = None,
key: str = None,
value: str = None):
if field is None and (key is None or value is None):
return self
try:
self.header_dict["user_fields"]
except KeyError:
self.header_dict["user_fields"] = []
if field is not None:
self.header_dict["user_fields"].append(field)
if key is not None and value is not None:
self.header_dict["user_fields"].append(
Mercury.UserField(key=key, value=value.encode()))
return self
def add_payload_part(self, part: bytes):
self.payload.append(part)
return self
def add_protobuf_payload(self, msg):
return self.add_payload_part(msg)
def build(self):
return RawMercuryRequest(Mercury.Header(**self.header_dict),
self.payload)

View file

@ -0,0 +1,283 @@
from __future__ import annotations
from librespot import util
from librespot.proto.ContextTrack_pb2 import ContextTrack
from librespot.util import Base62
import re
class SpotifyId:
STATIC_FROM_URI = "fromUri"
STATIC_FROM_BASE62 = "fromBase62"
STATIC_FROM_HEX = "fromHex"
@staticmethod
def from_base62(base62: str):
raise NotImplementedError
@staticmethod
def from_hex(hex_str: str):
raise NotImplementedError
@staticmethod
def from_uri(uri: str):
raise NotImplementedError
def to_spotify_uri(self) -> str:
raise NotImplementedError
class SpotifyIdParsingException(Exception):
pass
class PlayableId:
base62 = Base62.create_instance_with_inverted_character_set()
@staticmethod
def from_uri(uri: str) -> PlayableId:
if not PlayableId.is_supported(uri):
return UnsupportedId(uri)
if TrackId.pattern.search(uri) is not None:
return TrackId.from_uri(uri)
if EpisodeId.pattern.search(uri) is not None:
return EpisodeId.from_uri(uri)
raise TypeError("Unknown uri: {}".format(uri))
@staticmethod
def is_supported(uri: str):
return (not uri.startswith("spotify:local:")
and not uri == "spotify:delimiter"
and not uri == "spotify:meta:delimiter")
@staticmethod
def should_play(track: ContextTrack):
return track.metadata_or_default
def get_gid(self) -> bytes:
raise NotImplementedError
def hex_id(self) -> str:
raise NotImplementedError
def to_spotify_uri(self) -> str:
raise NotImplementedError
class PlaylistId(SpotifyId):
base62 = Base62.create_instance_with_inverted_character_set()
pattern = re.compile(r"spotify:playlist:(.{22})")
__id: str
def __init__(self, _id: str):
self.__id = _id
@staticmethod
def from_uri(uri: str) -> PlaylistId:
matcher = PlaylistId.pattern.search(uri)
if matcher is not None:
playlist_id = matcher.group(1)
return PlaylistId(playlist_id)
raise TypeError("Not a Spotify playlist ID: {}.".format(uri))
def id(self) -> str:
return self.__id
def to_spotify_uri(self) -> str:
return "spotify:playlist:" + self.__id
class UnsupportedId(PlayableId):
uri: str
def __init__(self, uri: str):
self.uri = uri
def get_gid(self) -> bytes:
raise TypeError()
def hex_id(self) -> str:
raise TypeError()
def to_spotify_uri(self) -> str:
return self.uri
class AlbumId(SpotifyId):
base62 = Base62.create_instance_with_inverted_character_set()
pattern = re.compile(r"spotify:album:(.{22})")
__hex_id: str
def __init__(self, hex_id: str):
self.__hex_id = hex_id.lower()
@staticmethod
def from_uri(uri: str) -> AlbumId:
matcher = AlbumId.pattern.search(uri)
if matcher is not None:
album_id = matcher.group(1)
return AlbumId(util.bytes_to_hex(AlbumId.base62.decode(album_id.encode(), 16)))
raise TypeError("Not a Spotify album ID: {}.".format(uri))
@staticmethod
def from_base62(base62: str) -> AlbumId:
return AlbumId(util.bytes_to_hex(AlbumId.base62.decode(base62.encode(), 16)))
@staticmethod
def from_hex(hex_str: str) -> AlbumId:
return AlbumId(hex_str)
def to_mercury_uri(self) -> str:
return "hm://metadata/4/album/{}".format(self.__hex_id)
def hex_id(self) -> str:
return self.__hex_id
def to_spotify_uri(self) -> str:
return "spotify:album:{}".format(
AlbumId.base62.encode(util.hex_to_bytes(self.__hex_id)).decode())
class ArtistId(SpotifyId):
base62 = Base62.create_instance_with_inverted_character_set()
pattern = re.compile("spotify:artist:(.{22})")
__hex_id: str
def __init__(self, hex_id: str):
self.__hex_id = hex_id.lower()
@staticmethod
def from_uri(uri: str) -> ArtistId:
matcher = ArtistId.pattern.search(uri)
if matcher is not None:
artist_id = matcher.group(1)
return ArtistId(
util.bytes_to_hex(ArtistId.base62.decode(artist_id.encode(), 16)))
raise TypeError("Not a Spotify artist ID: {}".format(uri))
@staticmethod
def from_base62(base62: str) -> ArtistId:
return ArtistId(util.bytes_to_hex(ArtistId.base62.decode(base62.encode(), 16)))
@staticmethod
def from_hex(hex_str: str) -> ArtistId:
return ArtistId(hex_str)
def to_mercury_uri(self) -> str:
return "hm://metadata/4/artist/{}".format(self.__hex_id)
def to_spotify_uri(self) -> str:
return "spotify:artist:{}".format(
ArtistId.base62.encode(util.hex_to_bytes(self.__hex_id)).decode())
def hex_id(self) -> str:
return self.__hex_id
class EpisodeId(SpotifyId, PlayableId):
pattern = re.compile(r"spotify:episode:(.{22})")
__hex_id: str
def __init__(self, hex_id: str):
self.__hex_id = hex_id.lower()
@staticmethod
def from_uri(uri: str) -> EpisodeId:
matcher = EpisodeId.pattern.search(uri)
if matcher is not None:
episode_id = matcher.group(1)
return EpisodeId(
util.bytes_to_hex(PlayableId.base62.decode(episode_id.encode(), 16)))
raise TypeError("Not a Spotify episode ID: {}".format(uri))
@staticmethod
def from_base62(base62: str) -> EpisodeId:
return EpisodeId(
util.bytes_to_hex(PlayableId.base62.decode(base62.encode(), 16)))
@staticmethod
def from_hex(hex_str: str) -> EpisodeId:
return EpisodeId(hex_str)
def to_mercury_uri(self) -> str:
return "hm://metadata/4/episode/{}".format(self.__hex_id)
def to_spotify_uri(self) -> str:
return "Spotify:episode:{}".format(
PlayableId.base62.encode(util.hex_to_bytes(self.__hex_id)).decode())
def hex_id(self) -> str:
return self.__hex_id
def get_gid(self) -> bytes:
return util.hex_to_bytes(self.__hex_id)
class ShowId(SpotifyId):
base62 = Base62.create_instance_with_inverted_character_set()
pattern = re.compile("spotify:show:(.{22})")
__hex_id: str
def __init__(self, hex_id: str):
self.__hex_id = hex_id
@staticmethod
def from_uri(uri: str) -> ShowId:
matcher = ShowId.pattern.search(uri)
if matcher is not None:
show_id = matcher.group(1)
return ShowId(util.bytes_to_hex(ShowId.base62.decode(show_id.encode(), 16)))
raise TypeError("Not a Spotify show ID: {}".format(uri))
@staticmethod
def from_base62(base62: str) -> ShowId:
return ShowId(util.bytes_to_hex(ShowId.base62.decode(base62.encode(), 16)))
@staticmethod
def from_hex(hex_str: str) -> ShowId:
return ShowId(hex_str)
def to_mercury_uri(self) -> str:
return "hm://metadata/4/show/{}".format(self.__hex_id)
def to_spotify_uri(self) -> str:
return "spotify:show:{}".format(
ShowId.base62.encode(util.hex_to_bytes(self.__hex_id)).decode())
def hex_id(self) -> str:
return self.__hex_id
class TrackId(PlayableId, SpotifyId):
pattern = re.compile("spotify:track:(.{22})")
__hex_id: str
def __init__(self, hex_id: str):
self.__hex_id = hex_id.lower()
@staticmethod
def from_uri(uri: str) -> TrackId:
search = TrackId.pattern.search(uri)
if search is not None:
track_id = search.group(1)
return TrackId(
util.bytes_to_hex(PlayableId.base62.decode(track_id.encode(), 16)))
raise RuntimeError("Not a Spotify track ID: {}".format(uri))
@staticmethod
def from_base62(base62: str) -> TrackId:
return TrackId(util.bytes_to_hex(PlayableId.base62.decode(base62.encode(), 16)))
@staticmethod
def from_hex(hex_str: str) -> TrackId:
return TrackId(hex_str)
def to_mercury_uri(self) -> str:
return "hm://metadata/4/track/{}".format(self.__hex_id)
def to_spotify_uri(self) -> str:
return "spotify:track:{}".format(TrackId.base62.encode(util.hex_to_bytes(self.__hex_id)).decode())
def hex_id(self) -> str:
return self.__hex_id
def get_gid(self) -> bytes:
return util.hex_to_bytes(self.__hex_id)

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: canvaz-meta.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import enum_type_wrapper
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="canvaz-meta.proto",
package="com.spotify.canvaz",
syntax="proto3",
serialized_options=b"\n\022com.spotify.canvazH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b"\n\x11\x63\x61nvaz-meta.proto\x12\x12\x63om.spotify.canvaz*R\n\x04Type\x12\t\n\x05IMAGE\x10\x00\x12\t\n\x05VIDEO\x10\x01\x12\x11\n\rVIDEO_LOOPING\x10\x02\x12\x18\n\x14VIDEO_LOOPING_RANDOM\x10\x03\x12\x07\n\x03GIF\x10\x04\x42\x16\n\x12\x63om.spotify.canvazH\x02\x62\x06proto3",
)
_TYPE = _descriptor.EnumDescriptor(
name="Type",
full_name="com.spotify.canvaz.Type",
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name="IMAGE",
index=0,
number=0,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="VIDEO",
index=1,
number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="VIDEO_LOOPING",
index=2,
number=2,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="VIDEO_LOOPING_RANDOM",
index=3,
number=3,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="GIF",
index=4,
number=4,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
],
containing_type=None,
serialized_options=None,
serialized_start=41,
serialized_end=123,
)
_sym_db.RegisterEnumDescriptor(_TYPE)
Type = enum_type_wrapper.EnumTypeWrapper(_TYPE)
IMAGE = 0
VIDEO = 1
VIDEO_LOOPING = 2
VIDEO_LOOPING_RANDOM = 3
GIF = 4
DESCRIPTOR.enum_types_by_name["Type"] = _TYPE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,564 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: canvaz.proto
"""Generated protocol buffer code."""
import CanvazMeta_pb2 as canvaz__meta__pb2
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="canvaz.proto",
package="com.spotify.canvazcache",
syntax="proto3",
serialized_options=b"\n\022com.spotify.canvazH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x0c\x63\x61nvaz.proto\x12\x17\x63om.spotify.canvazcache\x1a\x11\x63\x61nvaz-meta.proto"3\n\x06\x41rtist\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06\x61vatar\x18\x03 \x01(\t"\xe1\x02\n\x14\x45ntityCanvazResponse\x12\x46\n\x08\x63\x61nvases\x18\x01 \x03(\x0b\x32\x34.com.spotify.canvazcache.EntityCanvazResponse.Canvaz\x12\x16\n\x0ettl_in_seconds\x18\x02 \x01(\x03\x1a\xe8\x01\n\x06\x43\x61nvaz\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x0f\n\x07\x66ile_id\x18\x03 \x01(\t\x12&\n\x04type\x18\x04 \x01(\x0e\x32\x18.com.spotify.canvaz.Type\x12\x12\n\nentity_uri\x18\x05 \x01(\t\x12/\n\x06\x61rtist\x18\x06 \x01(\x0b\x32\x1f.com.spotify.canvazcache.Artist\x12\x10\n\x08\x65xplicit\x18\x07 \x01(\x08\x12\x13\n\x0buploaded_by\x18\x08 \x01(\t\x12\x0c\n\x04\x65tag\x18\t \x01(\t\x12\x12\n\ncanvas_uri\x18\x0b \x01(\t"\x88\x01\n\x13\x45ntityCanvazRequest\x12\x45\n\x08\x65ntities\x18\x01 \x03(\x0b\x32\x33.com.spotify.canvazcache.EntityCanvazRequest.Entity\x1a*\n\x06\x45ntity\x12\x12\n\nentity_uri\x18\x01 \x01(\t\x12\x0c\n\x04\x65tag\x18\x02 \x01(\tB\x16\n\x12\x63om.spotify.canvazH\x02\x62\x06proto3',
dependencies=[
canvaz__meta__pb2.DESCRIPTOR,
],
)
_ARTIST = _descriptor.Descriptor(
name="Artist",
full_name="com.spotify.canvazcache.Artist",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="uri",
full_name="com.spotify.canvazcache.Artist.uri",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="name",
full_name="com.spotify.canvazcache.Artist.name",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="avatar",
full_name="com.spotify.canvazcache.Artist.avatar",
index=2,
number=3,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=60,
serialized_end=111,
)
_ENTITYCANVAZRESPONSE_CANVAZ = _descriptor.Descriptor(
name="Canvaz",
full_name="com.spotify.canvazcache.EntityCanvazResponse.Canvaz",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="id",
full_name="com.spotify.canvazcache.EntityCanvazResponse.Canvaz.id",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="url",
full_name="com.spotify.canvazcache.EntityCanvazResponse.Canvaz.url",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="file_id",
full_name=
"com.spotify.canvazcache.EntityCanvazResponse.Canvaz.file_id",
index=2,
number=3,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="type",
full_name=
"com.spotify.canvazcache.EntityCanvazResponse.Canvaz.type",
index=3,
number=4,
type=14,
cpp_type=8,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="entity_uri",
full_name=
"com.spotify.canvazcache.EntityCanvazResponse.Canvaz.entity_uri",
index=4,
number=5,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="artist",
full_name=
"com.spotify.canvazcache.EntityCanvazResponse.Canvaz.artist",
index=5,
number=6,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="explicit",
full_name=
"com.spotify.canvazcache.EntityCanvazResponse.Canvaz.explicit",
index=6,
number=7,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="uploaded_by",
full_name=
"com.spotify.canvazcache.EntityCanvazResponse.Canvaz.uploaded_by",
index=7,
number=8,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="etag",
full_name=
"com.spotify.canvazcache.EntityCanvazResponse.Canvaz.etag",
index=8,
number=9,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="canvas_uri",
full_name=
"com.spotify.canvazcache.EntityCanvazResponse.Canvaz.canvas_uri",
index=9,
number=11,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=235,
serialized_end=467,
)
_ENTITYCANVAZRESPONSE = _descriptor.Descriptor(
name="EntityCanvazResponse",
full_name="com.spotify.canvazcache.EntityCanvazResponse",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="canvases",
full_name="com.spotify.canvazcache.EntityCanvazResponse.canvases",
index=0,
number=1,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="ttl_in_seconds",
full_name=
"com.spotify.canvazcache.EntityCanvazResponse.ttl_in_seconds",
index=1,
number=2,
type=3,
cpp_type=2,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[
_ENTITYCANVAZRESPONSE_CANVAZ,
],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=114,
serialized_end=467,
)
_ENTITYCANVAZREQUEST_ENTITY = _descriptor.Descriptor(
name="Entity",
full_name="com.spotify.canvazcache.EntityCanvazRequest.Entity",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="entity_uri",
full_name=
"com.spotify.canvazcache.EntityCanvazRequest.Entity.entity_uri",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="etag",
full_name="com.spotify.canvazcache.EntityCanvazRequest.Entity.etag",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=564,
serialized_end=606,
)
_ENTITYCANVAZREQUEST = _descriptor.Descriptor(
name="EntityCanvazRequest",
full_name="com.spotify.canvazcache.EntityCanvazRequest",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="entities",
full_name="com.spotify.canvazcache.EntityCanvazRequest.entities",
index=0,
number=1,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[
_ENTITYCANVAZREQUEST_ENTITY,
],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=470,
serialized_end=606,
)
_ENTITYCANVAZRESPONSE_CANVAZ.fields_by_name[
"type"].enum_type = canvaz__meta__pb2._TYPE
_ENTITYCANVAZRESPONSE_CANVAZ.fields_by_name["artist"].message_type = _ARTIST
_ENTITYCANVAZRESPONSE_CANVAZ.containing_type = _ENTITYCANVAZRESPONSE
_ENTITYCANVAZRESPONSE.fields_by_name[
"canvases"].message_type = _ENTITYCANVAZRESPONSE_CANVAZ
_ENTITYCANVAZREQUEST_ENTITY.containing_type = _ENTITYCANVAZREQUEST
_ENTITYCANVAZREQUEST.fields_by_name[
"entities"].message_type = _ENTITYCANVAZREQUEST_ENTITY
DESCRIPTOR.message_types_by_name["Artist"] = _ARTIST
DESCRIPTOR.message_types_by_name[
"EntityCanvazResponse"] = _ENTITYCANVAZRESPONSE
DESCRIPTOR.message_types_by_name["EntityCanvazRequest"] = _ENTITYCANVAZREQUEST
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Artist = _reflection.GeneratedProtocolMessageType(
"Artist",
(_message.Message, ),
{
"DESCRIPTOR": _ARTIST,
"__module__": "canvaz_pb2"
# @@protoc_insertion_point(class_scope:com.spotify.canvazcache.Artist)
},
)
_sym_db.RegisterMessage(Artist)
EntityCanvazResponse = _reflection.GeneratedProtocolMessageType(
"EntityCanvazResponse",
(_message.Message, ),
{
"Canvaz":
_reflection.GeneratedProtocolMessageType(
"Canvaz",
(_message.Message, ),
{
"DESCRIPTOR": _ENTITYCANVAZRESPONSE_CANVAZ,
"__module__": "canvaz_pb2"
# @@protoc_insertion_point(class_scope:com.spotify.canvazcache.EntityCanvazResponse.Canvaz)
},
),
"DESCRIPTOR":
_ENTITYCANVAZRESPONSE,
"__module__":
"canvaz_pb2"
# @@protoc_insertion_point(class_scope:com.spotify.canvazcache.EntityCanvazResponse)
},
)
_sym_db.RegisterMessage(EntityCanvazResponse)
_sym_db.RegisterMessage(EntityCanvazResponse.Canvaz)
EntityCanvazRequest = _reflection.GeneratedProtocolMessageType(
"EntityCanvazRequest",
(_message.Message, ),
{
"Entity":
_reflection.GeneratedProtocolMessageType(
"Entity",
(_message.Message, ),
{
"DESCRIPTOR": _ENTITYCANVAZREQUEST_ENTITY,
"__module__": "canvaz_pb2"
# @@protoc_insertion_point(class_scope:com.spotify.canvazcache.EntityCanvazRequest.Entity)
},
),
"DESCRIPTOR":
_ENTITYCANVAZREQUEST,
"__module__":
"canvaz_pb2"
# @@protoc_insertion_point(class_scope:com.spotify.canvazcache.EntityCanvazRequest)
},
)
_sym_db.RegisterMessage(EntityCanvazRequest)
_sym_db.RegisterMessage(EntityCanvazRequest.Entity)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: client_token.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from librespot.proto import Connectivity_pb2 as connectivity__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x63lient_token.proto\x12\x1bspotify.clienttoken.http.v0\x1a\x12\x63onnectivity.proto\"\x84\x02\n\x12\x43lientTokenRequest\x12I\n\x0crequest_type\x18\x01 \x01(\x0e\x32\x33.spotify.clienttoken.http.v0.ClientTokenRequestType\x12\x45\n\x0b\x63lient_data\x18\x02 \x01(\x0b\x32..spotify.clienttoken.http.v0.ClientDataRequestH\x00\x12Q\n\x11\x63hallenge_answers\x18\x03 \x01(\x0b\x32\x34.spotify.clienttoken.http.v0.ChallengeAnswersRequestH\x00\x42\t\n\x07request\"\x99\x01\n\x11\x43lientDataRequest\x12\x16\n\x0e\x63lient_version\x18\x01 \x01(\t\x12\x11\n\tclient_id\x18\x02 \x01(\t\x12Q\n\x15\x63onnectivity_sdk_data\x18\x03 \x01(\x0b\x32\x30.spotify.clienttoken.data.v0.ConnectivitySdkDataH\x00\x42\x06\n\x04\x64\x61ta\"g\n\x17\x43hallengeAnswersRequest\x12\r\n\x05state\x18\x01 \x01(\t\x12=\n\x07\x61nswers\x18\x02 \x03(\x0b\x32,.spotify.clienttoken.http.v0.ChallengeAnswer\"\x81\x02\n\x13\x43lientTokenResponse\x12K\n\rresponse_type\x18\x01 \x01(\x0e\x32\x34.spotify.clienttoken.http.v0.ClientTokenResponseType\x12J\n\rgranted_token\x18\x02 \x01(\x0b\x32\x31.spotify.clienttoken.http.v0.GrantedTokenResponseH\x00\x12\x45\n\nchallenges\x18\x03 \x01(\x0b\x32/.spotify.clienttoken.http.v0.ChallengesResponseH\x00\x42\n\n\x08response\"\x1d\n\x0bTokenDomain\x12\x0e\n\x06\x64omain\x18\x01 \x01(\t\"\x9e\x01\n\x14GrantedTokenResponse\x12\r\n\x05token\x18\x01 \x01(\t\x12\x1d\n\x15\x65xpires_after_seconds\x18\x02 \x01(\x05\x12\x1d\n\x15refresh_after_seconds\x18\x03 \x01(\x05\x12\x39\n\x07\x64omains\x18\x04 \x03(\x0b\x32(.spotify.clienttoken.http.v0.TokenDomain\"_\n\x12\x43hallengesResponse\x12\r\n\x05state\x18\x01 \x01(\t\x12:\n\nchallenges\x18\x02 \x03(\x0b\x32&.spotify.clienttoken.http.v0.Challenge\"&\n\x16\x43lientSecretParameters\x12\x0c\n\x04salt\x18\x01 \x01(\t\"7\n\x14\x45valuateJSParameters\x12\x0c\n\x04\x63ode\x18\x01 \x01(\t\x12\x11\n\tlibraries\x18\x02 \x03(\t\"4\n\x12HashCashParameters\x12\x0e\n\x06length\x18\x01 \x01(\x05\x12\x0e\n\x06prefix\x18\x02 \x01(\t\"\xda\x02\n\tChallenge\x12\x38\n\x04type\x18\x01 \x01(\x0e\x32*.spotify.clienttoken.http.v0.ChallengeType\x12W\n\x18\x63lient_secret_parameters\x18\x02 \x01(\x0b\x32\x33.spotify.clienttoken.http.v0.ClientSecretParametersH\x00\x12S\n\x16\x65valuate_js_parameters\x18\x03 \x01(\x0b\x32\x31.spotify.clienttoken.http.v0.EvaluateJSParametersH\x00\x12W\n\x1c\x65valuate_hashcash_parameters\x18\x04 \x01(\x0b\x32/.spotify.clienttoken.http.v0.HashCashParametersH\x00\x42\x0c\n\nparameters\"&\n\x16\x43lientSecretHMACAnswer\x12\x0c\n\x04hmac\x18\x01 \x01(\t\"\"\n\x10\x45valuateJSAnswer\x12\x0e\n\x06result\x18\x01 \x01(\t\" \n\x0eHashCashAnswer\x12\x0e\n\x06suffix\x18\x01 \x01(\t\"\xb4\x02\n\x0f\x43hallengeAnswer\x12\x41\n\rChallengeType\x18\x01 \x01(\x0e\x32*.spotify.clienttoken.http.v0.ChallengeType\x12L\n\rclient_secret\x18\x02 \x01(\x0b\x32\x33.spotify.clienttoken.http.v0.ClientSecretHMACAnswerH\x00\x12\x44\n\x0b\x65valuate_js\x18\x03 \x01(\x0b\x32-.spotify.clienttoken.http.v0.EvaluateJSAnswerH\x00\x12@\n\thash_cash\x18\x04 \x01(\x0b\x32+.spotify.clienttoken.http.v0.HashCashAnswerH\x00\x42\x08\n\x06\x61nswer\"(\n\x15\x43lientTokenBadRequest\x12\x0f\n\x07message\x18\x01 \x01(\t*u\n\x16\x43lientTokenRequestType\x12\x13\n\x0fREQUEST_UNKNOWN\x10\x00\x12\x1f\n\x1bREQUEST_CLIENT_DATA_REQUEST\x10\x01\x12%\n!REQUEST_CHALLENGE_ANSWERS_REQUEST\x10\x02*v\n\x17\x43lientTokenResponseType\x12\x14\n\x10RESPONSE_UNKNOWN\x10\x00\x12#\n\x1fRESPONSE_GRANTED_TOKEN_RESPONSE\x10\x01\x12 \n\x1cRESPONSE_CHALLENGES_RESPONSE\x10\x02*|\n\rChallengeType\x12\x15\n\x11\x43HALLENGE_UNKNOWN\x10\x00\x12 \n\x1c\x43HALLENGE_CLIENT_SECRET_HMAC\x10\x01\x12\x19\n\x15\x43HALLENGE_EVALUATE_JS\x10\x02\x12\x17\n\x13\x43HALLENGE_HASH_CASH\x10\x03\x42#\n\x1f\x63om.spotify.clienttoken.http.v0H\x02\x62\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'client_token_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\037com.spotify.clienttoken.http.v0H\002'
_CLIENTTOKENREQUESTTYPE._serialized_start=2107
_CLIENTTOKENREQUESTTYPE._serialized_end=2224
_CLIENTTOKENRESPONSETYPE._serialized_start=2226
_CLIENTTOKENRESPONSETYPE._serialized_end=2344
_CHALLENGETYPE._serialized_start=2346
_CHALLENGETYPE._serialized_end=2470
_CLIENTTOKENREQUEST._serialized_start=72
_CLIENTTOKENREQUEST._serialized_end=332
_CLIENTDATAREQUEST._serialized_start=335
_CLIENTDATAREQUEST._serialized_end=488
_CHALLENGEANSWERSREQUEST._serialized_start=490
_CHALLENGEANSWERSREQUEST._serialized_end=593
_CLIENTTOKENRESPONSE._serialized_start=596
_CLIENTTOKENRESPONSE._serialized_end=853
_TOKENDOMAIN._serialized_start=855
_TOKENDOMAIN._serialized_end=884
_GRANTEDTOKENRESPONSE._serialized_start=887
_GRANTEDTOKENRESPONSE._serialized_end=1045
_CHALLENGESRESPONSE._serialized_start=1047
_CHALLENGESRESPONSE._serialized_end=1142
_CLIENTSECRETPARAMETERS._serialized_start=1144
_CLIENTSECRETPARAMETERS._serialized_end=1182
_EVALUATEJSPARAMETERS._serialized_start=1184
_EVALUATEJSPARAMETERS._serialized_end=1239
_HASHCASHPARAMETERS._serialized_start=1241
_HASHCASHPARAMETERS._serialized_end=1293
_CHALLENGE._serialized_start=1296
_CHALLENGE._serialized_end=1642
_CLIENTSECRETHMACANSWER._serialized_start=1644
_CLIENTSECRETHMACANSWER._serialized_end=1682
_EVALUATEJSANSWER._serialized_start=1684
_EVALUATEJSANSWER._serialized_end=1718
_HASHCASHANSWER._serialized_start=1720
_HASHCASHANSWER._serialized_end=1752
_CHALLENGEANSWER._serialized_start=1755
_CHALLENGEANSWER._serialized_end=2063
_CLIENTTOKENBADREQUEST._serialized_start=2065
_CLIENTTOKENBADREQUEST._serialized_end=2105
# @@protoc_insertion_point(module_scope)

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: connectivity.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x63onnectivity.proto\x12\x1bspotify.clienttoken.data.v0\"{\n\x13\x43onnectivitySdkData\x12Q\n\x16platform_specific_data\x18\x01 \x01(\x0b\x32\x31.spotify.clienttoken.data.v0.PlatformSpecificData\x12\x11\n\tdevice_id\x18\x02 \x01(\t\"\xdf\x01\n\x14PlatformSpecificData\x12\x41\n\x07\x61ndroid\x18\x01 \x01(\x0b\x32..spotify.clienttoken.data.v0.NativeAndroidDataH\x00\x12\x39\n\x03ios\x18\x02 \x01(\x0b\x32*.spotify.clienttoken.data.v0.NativeIOSDataH\x00\x12\x41\n\x07windows\x18\x04 \x01(\x0b\x32..spotify.clienttoken.data.v0.NativeWindowsDataH\x00\x42\x06\n\x04\x64\x61ta\"\xb9\x01\n\x11NativeAndroidData\x12\x19\n\x11major_sdk_version\x18\x01 \x01(\x05\x12\x19\n\x11minor_sdk_version\x18\x02 \x01(\x05\x12\x19\n\x11patch_sdk_version\x18\x03 \x01(\x05\x12\x13\n\x0b\x61pi_version\x18\x04 \x01(\r\x12>\n\x11screen_dimensions\x18\x05 \x01(\x0b\x32#.spotify.clienttoken.data.v0.Screen\"\x9e\x01\n\rNativeIOSData\x12\x1c\n\x14user_interface_idiom\x18\x01 \x01(\x05\x12\x1f\n\x17target_iphone_simulator\x18\x02 \x01(\x08\x12\x12\n\nhw_machine\x18\x03 \x01(\t\x12\x16\n\x0esystem_version\x18\x04 \x01(\t\x12\"\n\x1asimulator_model_identifier\x18\x05 \x01(\t\"\xa0\x01\n\x11NativeWindowsData\x12\x12\n\nsomething1\x18\x01 \x01(\x05\x12\x12\n\nsomething3\x18\x03 \x01(\x05\x12\x12\n\nsomething4\x18\x04 \x01(\x05\x12\x12\n\nsomething6\x18\x06 \x01(\x05\x12\x12\n\nsomething7\x18\x07 \x01(\x05\x12\x12\n\nsomething8\x18\x08 \x01(\x05\x12\x13\n\x0bsomething10\x18\n \x01(\x08\"8\n\x06Screen\x12\r\n\x05width\x18\x01 \x01(\x05\x12\x0e\n\x06height\x18\x02 \x01(\x05\x12\x0f\n\x07\x64\x65nsity\x18\x03 \x01(\x05\x42#\n\x1f\x63om.spotify.clienttoken.data.v0H\x02\x62\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'connectivity_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\037com.spotify.clienttoken.data.v0H\002'
_CONNECTIVITYSDKDATA._serialized_start=51
_CONNECTIVITYSDKDATA._serialized_end=174
_PLATFORMSPECIFICDATA._serialized_start=177
_PLATFORMSPECIFICDATA._serialized_end=400
_NATIVEANDROIDDATA._serialized_start=403
_NATIVEANDROIDDATA._serialized_end=588
_NATIVEIOSDATA._serialized_start=591
_NATIVEIOSDATA._serialized_end=749
_NATIVEWINDOWSDATA._serialized_start=752
_NATIVEWINDOWSDATA._serialized_end=912
_SCREEN._serialized_start=914
_SCREEN._serialized_end=970
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,239 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: context_page.proto
"""Generated protocol buffer code."""
import ContextTrack_pb2 as context__track__pb2
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="context_page.proto",
package="spotify.player.proto",
syntax="proto2",
serialized_options=b"\n\023com.spotify.contextH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x12\x63ontext_page.proto\x12\x14spotify.player.proto\x1a\x13\x63ontext_track.proto"\xef\x01\n\x0b\x43ontextPage\x12\x10\n\x08page_url\x18\x01 \x01(\t\x12\x15\n\rnext_page_url\x18\x02 \x01(\t\x12\x41\n\x08metadata\x18\x03 \x03(\x0b\x32/.spotify.player.proto.ContextPage.MetadataEntry\x12\x32\n\x06tracks\x18\x04 \x03(\x0b\x32".spotify.player.proto.ContextTrack\x12\x0f\n\x07loading\x18\x05 \x01(\x08\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x17\n\x13\x63om.spotify.contextH\x02',
dependencies=[
context__track__pb2.DESCRIPTOR,
],
)
_CONTEXTPAGE_METADATAENTRY = _descriptor.Descriptor(
name="MetadataEntry",
full_name="spotify.player.proto.ContextPage.MetadataEntry",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="key",
full_name="spotify.player.proto.ContextPage.MetadataEntry.key",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="value",
full_name="spotify.player.proto.ContextPage.MetadataEntry.value",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=b"8\001",
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=258,
serialized_end=305,
)
_CONTEXTPAGE = _descriptor.Descriptor(
name="ContextPage",
full_name="spotify.player.proto.ContextPage",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="page_url",
full_name="spotify.player.proto.ContextPage.page_url",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="next_page_url",
full_name="spotify.player.proto.ContextPage.next_page_url",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="metadata",
full_name="spotify.player.proto.ContextPage.metadata",
index=2,
number=3,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="tracks",
full_name="spotify.player.proto.ContextPage.tracks",
index=3,
number=4,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="loading",
full_name="spotify.player.proto.ContextPage.loading",
index=4,
number=5,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[
_CONTEXTPAGE_METADATAENTRY,
],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=66,
serialized_end=305,
)
_CONTEXTPAGE_METADATAENTRY.containing_type = _CONTEXTPAGE
_CONTEXTPAGE.fields_by_name[
"metadata"].message_type = _CONTEXTPAGE_METADATAENTRY
_CONTEXTPAGE.fields_by_name[
"tracks"].message_type = context__track__pb2._CONTEXTTRACK
DESCRIPTOR.message_types_by_name["ContextPage"] = _CONTEXTPAGE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
ContextPage = _reflection.GeneratedProtocolMessageType(
"ContextPage",
(_message.Message, ),
{
"MetadataEntry":
_reflection.GeneratedProtocolMessageType(
"MetadataEntry",
(_message.Message, ),
{
"DESCRIPTOR": _CONTEXTPAGE_METADATAENTRY,
"__module__": "context_page_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.ContextPage.MetadataEntry)
},
),
"DESCRIPTOR":
_CONTEXTPAGE,
"__module__":
"context_page_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.ContextPage)
},
)
_sym_db.RegisterMessage(ContextPage)
_sym_db.RegisterMessage(ContextPage.MetadataEntry)
DESCRIPTOR._options = None
_CONTEXTPAGE_METADATAENTRY._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,215 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: context_player_options.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="context_player_options.proto",
package="spotify.player.proto",
syntax="proto2",
serialized_options=b"\n\023com.spotify.contextH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x1c\x63ontext_player_options.proto\x12\x14spotify.player.proto"e\n\x14\x43ontextPlayerOptions\x12\x19\n\x11shuffling_context\x18\x01 \x01(\x08\x12\x19\n\x11repeating_context\x18\x02 \x01(\x08\x12\x17\n\x0frepeating_track\x18\x03 \x01(\x08"m\n\x1c\x43ontextPlayerOptionOverrides\x12\x19\n\x11shuffling_context\x18\x01 \x01(\x08\x12\x19\n\x11repeating_context\x18\x02 \x01(\x08\x12\x17\n\x0frepeating_track\x18\x03 \x01(\x08\x42\x17\n\x13\x63om.spotify.contextH\x02',
)
_CONTEXTPLAYEROPTIONS = _descriptor.Descriptor(
name="ContextPlayerOptions",
full_name="spotify.player.proto.ContextPlayerOptions",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="shuffling_context",
full_name=
"spotify.player.proto.ContextPlayerOptions.shuffling_context",
index=0,
number=1,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="repeating_context",
full_name=
"spotify.player.proto.ContextPlayerOptions.repeating_context",
index=1,
number=2,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="repeating_track",
full_name=
"spotify.player.proto.ContextPlayerOptions.repeating_track",
index=2,
number=3,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=54,
serialized_end=155,
)
_CONTEXTPLAYEROPTIONOVERRIDES = _descriptor.Descriptor(
name="ContextPlayerOptionOverrides",
full_name="spotify.player.proto.ContextPlayerOptionOverrides",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="shuffling_context",
full_name=
"spotify.player.proto.ContextPlayerOptionOverrides.shuffling_context",
index=0,
number=1,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="repeating_context",
full_name=
"spotify.player.proto.ContextPlayerOptionOverrides.repeating_context",
index=1,
number=2,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="repeating_track",
full_name=
"spotify.player.proto.ContextPlayerOptionOverrides.repeating_track",
index=2,
number=3,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=157,
serialized_end=266,
)
DESCRIPTOR.message_types_by_name[
"ContextPlayerOptions"] = _CONTEXTPLAYEROPTIONS
DESCRIPTOR.message_types_by_name[
"ContextPlayerOptionOverrides"] = _CONTEXTPLAYEROPTIONOVERRIDES
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
ContextPlayerOptions = _reflection.GeneratedProtocolMessageType(
"ContextPlayerOptions",
(_message.Message, ),
{
"DESCRIPTOR": _CONTEXTPLAYEROPTIONS,
"__module__": "context_player_options_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.ContextPlayerOptions)
},
)
_sym_db.RegisterMessage(ContextPlayerOptions)
ContextPlayerOptionOverrides = _reflection.GeneratedProtocolMessageType(
"ContextPlayerOptionOverrides",
(_message.Message, ),
{
"DESCRIPTOR": _CONTEXTPLAYEROPTIONOVERRIDES,
"__module__": "context_player_options_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.ContextPlayerOptionOverrides)
},
)
_sym_db.RegisterMessage(ContextPlayerOptionOverrides)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,214 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: context_track.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="context_track.proto",
package="spotify.player.proto",
syntax="proto2",
serialized_options=b"\n\023com.spotify.contextH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x13\x63ontext_track.proto\x12\x14spotify.player.proto"\xaa\x01\n\x0c\x43ontextTrack\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12\x0b\n\x03uid\x18\x02 \x01(\t\x12\x0b\n\x03gid\x18\x03 \x01(\x0c\x12\x42\n\x08metadata\x18\x04 \x03(\x0b\x32\x30.spotify.player.proto.ContextTrack.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x17\n\x13\x63om.spotify.contextH\x02',
)
_CONTEXTTRACK_METADATAENTRY = _descriptor.Descriptor(
name="MetadataEntry",
full_name="spotify.player.proto.ContextTrack.MetadataEntry",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="key",
full_name="spotify.player.proto.ContextTrack.MetadataEntry.key",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="value",
full_name="spotify.player.proto.ContextTrack.MetadataEntry.value",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=b"8\001",
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=169,
serialized_end=216,
)
_CONTEXTTRACK = _descriptor.Descriptor(
name="ContextTrack",
full_name="spotify.player.proto.ContextTrack",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="uri",
full_name="spotify.player.proto.ContextTrack.uri",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="uid",
full_name="spotify.player.proto.ContextTrack.uid",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="gid",
full_name="spotify.player.proto.ContextTrack.gid",
index=2,
number=3,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="metadata",
full_name="spotify.player.proto.ContextTrack.metadata",
index=3,
number=4,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[
_CONTEXTTRACK_METADATAENTRY,
],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=46,
serialized_end=216,
)
_CONTEXTTRACK_METADATAENTRY.containing_type = _CONTEXTTRACK
_CONTEXTTRACK.fields_by_name[
"metadata"].message_type = _CONTEXTTRACK_METADATAENTRY
DESCRIPTOR.message_types_by_name["ContextTrack"] = _CONTEXTTRACK
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
ContextTrack = _reflection.GeneratedProtocolMessageType(
"ContextTrack",
(_message.Message, ),
{
"MetadataEntry":
_reflection.GeneratedProtocolMessageType(
"MetadataEntry",
(_message.Message, ),
{
"DESCRIPTOR": _CONTEXTTRACK_METADATAENTRY,
"__module__": "context_track_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.ContextTrack.MetadataEntry)
},
),
"DESCRIPTOR":
_CONTEXTTRACK,
"__module__":
"context_track_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.ContextTrack)
},
)
_sym_db.RegisterMessage(ContextTrack)
_sym_db.RegisterMessage(ContextTrack.MetadataEntry)
DESCRIPTOR._options = None
_CONTEXTTRACK_METADATAENTRY._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,260 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: context.proto
"""Generated protocol buffer code."""
import ContextPage_pb2 as context__page__pb2
import Restrictions_pb2 as restrictions__pb2
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="context.proto",
package="spotify.player.proto",
syntax="proto2",
serialized_options=b"\n\023com.spotify.contextH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\rcontext.proto\x12\x14spotify.player.proto\x1a\x12\x63ontext_page.proto\x1a\x12restrictions.proto"\x90\x02\n\x07\x43ontext\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12=\n\x08metadata\x18\x03 \x03(\x0b\x32+.spotify.player.proto.Context.MetadataEntry\x12\x38\n\x0crestrictions\x18\x04 \x01(\x0b\x32".spotify.player.proto.Restrictions\x12\x30\n\x05pages\x18\x05 \x03(\x0b\x32!.spotify.player.proto.ContextPage\x12\x0f\n\x07loading\x18\x06 \x01(\x08\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x17\n\x13\x63om.spotify.contextH\x02',
dependencies=[
context__page__pb2.DESCRIPTOR,
restrictions__pb2.DESCRIPTOR,
],
)
_CONTEXT_METADATAENTRY = _descriptor.Descriptor(
name="MetadataEntry",
full_name="spotify.player.proto.Context.MetadataEntry",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="key",
full_name="spotify.player.proto.Context.MetadataEntry.key",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="value",
full_name="spotify.player.proto.Context.MetadataEntry.value",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=b"8\001",
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=305,
serialized_end=352,
)
_CONTEXT = _descriptor.Descriptor(
name="Context",
full_name="spotify.player.proto.Context",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="uri",
full_name="spotify.player.proto.Context.uri",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="url",
full_name="spotify.player.proto.Context.url",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="metadata",
full_name="spotify.player.proto.Context.metadata",
index=2,
number=3,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="restrictions",
full_name="spotify.player.proto.Context.restrictions",
index=3,
number=4,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="pages",
full_name="spotify.player.proto.Context.pages",
index=4,
number=5,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="loading",
full_name="spotify.player.proto.Context.loading",
index=5,
number=6,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[
_CONTEXT_METADATAENTRY,
],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=80,
serialized_end=352,
)
_CONTEXT_METADATAENTRY.containing_type = _CONTEXT
_CONTEXT.fields_by_name["metadata"].message_type = _CONTEXT_METADATAENTRY
_CONTEXT.fields_by_name[
"restrictions"].message_type = restrictions__pb2._RESTRICTIONS
_CONTEXT.fields_by_name["pages"].message_type = context__page__pb2._CONTEXTPAGE
DESCRIPTOR.message_types_by_name["Context"] = _CONTEXT
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Context = _reflection.GeneratedProtocolMessageType(
"Context",
(_message.Message, ),
{
"MetadataEntry":
_reflection.GeneratedProtocolMessageType(
"MetadataEntry",
(_message.Message, ),
{
"DESCRIPTOR": _CONTEXT_METADATAENTRY,
"__module__": "context_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.Context.MetadataEntry)
},
),
"DESCRIPTOR":
_CONTEXT,
"__module__":
"context_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.Context)
},
)
_sym_db.RegisterMessage(Context)
_sym_db.RegisterMessage(Context.MetadataEntry)
DESCRIPTOR._options = None
_CONTEXT_METADATAENTRY._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,147 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: explicit_content_pubsub.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='explicit_content_pubsub.proto',
package='spotify.explicit_content.proto',
syntax='proto2',
serialized_options=b'\n\024com.spotify.explicitH\002',
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x1d\x65xplicit_content_pubsub.proto\x12\x1espotify.explicit_content.proto\"*\n\x0cKeyValuePair\x12\x0b\n\x03key\x18\x01 \x02(\t\x12\r\n\x05value\x18\x02 \x02(\t\"S\n\x14UserAttributesUpdate\x12;\n\x05pairs\x18\x01 \x03(\x0b\x32,.spotify.explicit_content.proto.KeyValuePairB\x18\n\x14\x63om.spotify.explicitH\x02'
)
_KEYVALUEPAIR = _descriptor.Descriptor(
name='KeyValuePair',
full_name='spotify.explicit_content.proto.KeyValuePair',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='key',
full_name='spotify.explicit_content.proto.KeyValuePair.key',
index=0,
number=1,
type=9,
cpp_type=9,
label=2,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='value',
full_name='spotify.explicit_content.proto.KeyValuePair.value',
index=1,
number=2,
type=9,
cpp_type=9,
label=2,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[],
serialized_start=65,
serialized_end=107,
)
_USERATTRIBUTESUPDATE = _descriptor.Descriptor(
name='UserAttributesUpdate',
full_name='spotify.explicit_content.proto.UserAttributesUpdate',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='pairs',
full_name=
'spotify.explicit_content.proto.UserAttributesUpdate.pairs',
index=0,
number=1,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[],
serialized_start=109,
serialized_end=192,
)
_USERATTRIBUTESUPDATE.fields_by_name['pairs'].message_type = _KEYVALUEPAIR
DESCRIPTOR.message_types_by_name['KeyValuePair'] = _KEYVALUEPAIR
DESCRIPTOR.message_types_by_name[
'UserAttributesUpdate'] = _USERATTRIBUTESUPDATE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
KeyValuePair = _reflection.GeneratedProtocolMessageType(
'KeyValuePair',
(_message.Message, ),
{
'DESCRIPTOR': _KEYVALUEPAIR,
'__module__': 'explicit_content_pubsub_pb2'
# @@protoc_insertion_point(class_scope:spotify.explicit_content.proto.KeyValuePair)
})
_sym_db.RegisterMessage(KeyValuePair)
UserAttributesUpdate = _reflection.GeneratedProtocolMessageType(
'UserAttributesUpdate',
(_message.Message, ),
{
'DESCRIPTOR': _USERATTRIBUTESUPDATE,
'__module__': 'explicit_content_pubsub_pb2'
# @@protoc_insertion_point(class_scope:spotify.explicit_content.proto.UserAttributesUpdate)
})
_sym_db.RegisterMessage(UserAttributesUpdate)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,625 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mercury.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='mercury.proto',
package='spotify',
syntax='proto2',
serialized_options=b'\n\013com.spotify',
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\rmercury.proto\x12\x07spotify\"B\n\x16MercuryMultiGetRequest\x12(\n\x07request\x18\x01 \x03(\x0b\x32\x17.spotify.MercuryRequest\"<\n\x14MercuryMultiGetReply\x12$\n\x05reply\x18\x01 \x03(\x0b\x32\x15.spotify.MercuryReply\"O\n\x0eMercuryRequest\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12\x14\n\x0c\x63ontent_type\x18\x02 \x01(\t\x12\x0c\n\x04\x62ody\x18\x03 \x01(\x0c\x12\x0c\n\x04\x65tag\x18\x04 \x01(\x0c\"\xf5\x01\n\x0cMercuryReply\x12\x13\n\x0bstatus_code\x18\x01 \x01(\x11\x12\x16\n\x0estatus_message\x18\x02 \x01(\t\x12\x37\n\x0c\x63\x61\x63he_policy\x18\x03 \x01(\x0e\x32!.spotify.MercuryReply.CachePolicy\x12\x0b\n\x03ttl\x18\x04 \x01(\x11\x12\x0c\n\x04\x65tag\x18\x05 \x01(\x0c\x12\x14\n\x0c\x63ontent_type\x18\x06 \x01(\t\x12\x0c\n\x04\x62ody\x18\x07 \x01(\x0c\"@\n\x0b\x43\x61\x63hePolicy\x12\x0c\n\x08\x43\x41\x43HE_NO\x10\x01\x12\x11\n\rCACHE_PRIVATE\x10\x02\x12\x10\n\x0c\x43\x41\x43HE_PUBLIC\x10\x03\"y\n\x06Header\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12\x14\n\x0c\x63ontent_type\x18\x02 \x01(\t\x12\x0e\n\x06method\x18\x03 \x01(\t\x12\x13\n\x0bstatus_code\x18\x04 \x01(\x11\x12\'\n\x0buser_fields\x18\x06 \x03(\x0b\x32\x12.spotify.UserField\"\'\n\tUserField\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x42\r\n\x0b\x63om.spotify'
)
_MERCURYREPLY_CACHEPOLICY = _descriptor.EnumDescriptor(
name='CachePolicy',
full_name='spotify.MercuryReply.CachePolicy',
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name='CACHE_NO',
index=0,
number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='CACHE_PRIVATE',
index=1,
number=2,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='CACHE_PUBLIC',
index=2,
number=3,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
],
containing_type=None,
serialized_options=None,
serialized_start=419,
serialized_end=483,
)
_sym_db.RegisterEnumDescriptor(_MERCURYREPLY_CACHEPOLICY)
_MERCURYMULTIGETREQUEST = _descriptor.Descriptor(
name='MercuryMultiGetRequest',
full_name='spotify.MercuryMultiGetRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='request',
full_name='spotify.MercuryMultiGetRequest.request',
index=0,
number=1,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[],
serialized_start=26,
serialized_end=92,
)
_MERCURYMULTIGETREPLY = _descriptor.Descriptor(
name='MercuryMultiGetReply',
full_name='spotify.MercuryMultiGetReply',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='reply',
full_name='spotify.MercuryMultiGetReply.reply',
index=0,
number=1,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[],
serialized_start=94,
serialized_end=154,
)
_MERCURYREQUEST = _descriptor.Descriptor(
name='MercuryRequest',
full_name='spotify.MercuryRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='uri',
full_name='spotify.MercuryRequest.uri',
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='content_type',
full_name='spotify.MercuryRequest.content_type',
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='body',
full_name='spotify.MercuryRequest.body',
index=2,
number=3,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='etag',
full_name='spotify.MercuryRequest.etag',
index=3,
number=4,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[],
serialized_start=156,
serialized_end=235,
)
_MERCURYREPLY = _descriptor.Descriptor(
name='MercuryReply',
full_name='spotify.MercuryReply',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='status_code',
full_name='spotify.MercuryReply.status_code',
index=0,
number=1,
type=17,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='status_message',
full_name='spotify.MercuryReply.status_message',
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='cache_policy',
full_name='spotify.MercuryReply.cache_policy',
index=2,
number=3,
type=14,
cpp_type=8,
label=1,
has_default_value=False,
default_value=1,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='ttl',
full_name='spotify.MercuryReply.ttl',
index=3,
number=4,
type=17,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='etag',
full_name='spotify.MercuryReply.etag',
index=4,
number=5,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='content_type',
full_name='spotify.MercuryReply.content_type',
index=5,
number=6,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='body',
full_name='spotify.MercuryReply.body',
index=6,
number=7,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[
_MERCURYREPLY_CACHEPOLICY,
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[],
serialized_start=238,
serialized_end=483,
)
_HEADER = _descriptor.Descriptor(
name='Header',
full_name='spotify.Header',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='uri',
full_name='spotify.Header.uri',
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='content_type',
full_name='spotify.Header.content_type',
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='method',
full_name='spotify.Header.method',
index=2,
number=3,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='status_code',
full_name='spotify.Header.status_code',
index=3,
number=4,
type=17,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='user_fields',
full_name='spotify.Header.user_fields',
index=4,
number=6,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[],
serialized_start=485,
serialized_end=606,
)
_USERFIELD = _descriptor.Descriptor(
name='UserField',
full_name='spotify.UserField',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='key',
full_name='spotify.UserField.key',
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='value',
full_name='spotify.UserField.value',
index=1,
number=2,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[],
serialized_start=608,
serialized_end=647,
)
_MERCURYMULTIGETREQUEST.fields_by_name[
'request'].message_type = _MERCURYREQUEST
_MERCURYMULTIGETREPLY.fields_by_name['reply'].message_type = _MERCURYREPLY
_MERCURYREPLY.fields_by_name[
'cache_policy'].enum_type = _MERCURYREPLY_CACHEPOLICY
_MERCURYREPLY_CACHEPOLICY.containing_type = _MERCURYREPLY
_HEADER.fields_by_name['user_fields'].message_type = _USERFIELD
DESCRIPTOR.message_types_by_name[
'MercuryMultiGetRequest'] = _MERCURYMULTIGETREQUEST
DESCRIPTOR.message_types_by_name[
'MercuryMultiGetReply'] = _MERCURYMULTIGETREPLY
DESCRIPTOR.message_types_by_name['MercuryRequest'] = _MERCURYREQUEST
DESCRIPTOR.message_types_by_name['MercuryReply'] = _MERCURYREPLY
DESCRIPTOR.message_types_by_name['Header'] = _HEADER
DESCRIPTOR.message_types_by_name['UserField'] = _USERFIELD
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
MercuryMultiGetRequest = _reflection.GeneratedProtocolMessageType(
'MercuryMultiGetRequest',
(_message.Message, ),
{
'DESCRIPTOR': _MERCURYMULTIGETREQUEST,
'__module__': 'mercury_pb2'
# @@protoc_insertion_point(class_scope:spotify.MercuryMultiGetRequest)
})
_sym_db.RegisterMessage(MercuryMultiGetRequest)
MercuryMultiGetReply = _reflection.GeneratedProtocolMessageType(
'MercuryMultiGetReply',
(_message.Message, ),
{
'DESCRIPTOR': _MERCURYMULTIGETREPLY,
'__module__': 'mercury_pb2'
# @@protoc_insertion_point(class_scope:spotify.MercuryMultiGetReply)
})
_sym_db.RegisterMessage(MercuryMultiGetReply)
MercuryRequest = _reflection.GeneratedProtocolMessageType(
'MercuryRequest',
(_message.Message, ),
{
'DESCRIPTOR': _MERCURYREQUEST,
'__module__': 'mercury_pb2'
# @@protoc_insertion_point(class_scope:spotify.MercuryRequest)
})
_sym_db.RegisterMessage(MercuryRequest)
MercuryReply = _reflection.GeneratedProtocolMessageType(
'MercuryReply',
(_message.Message, ),
{
'DESCRIPTOR': _MERCURYREPLY,
'__module__': 'mercury_pb2'
# @@protoc_insertion_point(class_scope:spotify.MercuryReply)
})
_sym_db.RegisterMessage(MercuryReply)
Header = _reflection.GeneratedProtocolMessageType(
'Header',
(_message.Message, ),
{
'DESCRIPTOR': _HEADER,
'__module__': 'mercury_pb2'
# @@protoc_insertion_point(class_scope:spotify.Header)
})
_sym_db.RegisterMessage(Header)
UserField = _reflection.GeneratedProtocolMessageType(
'UserField',
(_message.Message, ),
{
'DESCRIPTOR': _USERFIELD,
'__module__': 'mercury_pb2'
# @@protoc_insertion_point(class_scope:spotify.UserField)
})
_sym_db.RegisterMessage(UserField)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,193 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: play_origin.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="play_origin.proto",
package="spotify.player.proto",
syntax="proto2",
serialized_options=b"\n\023com.spotify.contextH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x11play_origin.proto\x12\x14spotify.player.proto"\xbf\x01\n\nPlayOrigin\x12\x1a\n\x12\x66\x65\x61ture_identifier\x18\x01 \x01(\t\x12\x17\n\x0f\x66\x65\x61ture_version\x18\x02 \x01(\t\x12\x10\n\x08view_uri\x18\x03 \x01(\t\x12\x19\n\x11\x65xternal_referrer\x18\x04 \x01(\t\x12\x1b\n\x13referrer_identifier\x18\x05 \x01(\t\x12\x19\n\x11\x64\x65vice_identifier\x18\x06 \x01(\t\x12\x17\n\x0f\x66\x65\x61ture_classes\x18\x07 \x03(\tB\x17\n\x13\x63om.spotify.contextH\x02',
)
_PLAYORIGIN = _descriptor.Descriptor(
name="PlayOrigin",
full_name="spotify.player.proto.PlayOrigin",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="feature_identifier",
full_name="spotify.player.proto.PlayOrigin.feature_identifier",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="feature_version",
full_name="spotify.player.proto.PlayOrigin.feature_version",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="view_uri",
full_name="spotify.player.proto.PlayOrigin.view_uri",
index=2,
number=3,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="external_referrer",
full_name="spotify.player.proto.PlayOrigin.external_referrer",
index=3,
number=4,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="referrer_identifier",
full_name="spotify.player.proto.PlayOrigin.referrer_identifier",
index=4,
number=5,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="device_identifier",
full_name="spotify.player.proto.PlayOrigin.device_identifier",
index=5,
number=6,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="feature_classes",
full_name="spotify.player.proto.PlayOrigin.feature_classes",
index=6,
number=7,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=44,
serialized_end=235,
)
DESCRIPTOR.message_types_by_name["PlayOrigin"] = _PLAYORIGIN
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
PlayOrigin = _reflection.GeneratedProtocolMessageType(
"PlayOrigin",
(_message.Message, ),
{
"DESCRIPTOR": _PLAYORIGIN,
"__module__": "play_origin_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.PlayOrigin)
},
)
_sym_db.RegisterMessage(PlayOrigin)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,162 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: playback.proto
"""Generated protocol buffer code."""
import ContextTrack_pb2 as context__track__pb2
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="playback.proto",
package="spotify.player.proto.transfer",
syntax="proto2",
serialized_options=b"\n\024com.spotify.transferH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x0eplayback.proto\x12\x1dspotify.player.proto.transfer\x1a\x13\x63ontext_track.proto"\xa5\x01\n\x08Playback\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\x12 \n\x18position_as_of_timestamp\x18\x02 \x01(\x05\x12\x16\n\x0eplayback_speed\x18\x03 \x01(\x01\x12\x11\n\tis_paused\x18\x04 \x01(\x08\x12\x39\n\rcurrent_track\x18\x05 \x01(\x0b\x32".spotify.player.proto.ContextTrackB\x18\n\x14\x63om.spotify.transferH\x02',
dependencies=[
context__track__pb2.DESCRIPTOR,
],
)
_PLAYBACK = _descriptor.Descriptor(
name="Playback",
full_name="spotify.player.proto.transfer.Playback",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="timestamp",
full_name="spotify.player.proto.transfer.Playback.timestamp",
index=0,
number=1,
type=3,
cpp_type=2,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="position_as_of_timestamp",
full_name=
"spotify.player.proto.transfer.Playback.position_as_of_timestamp",
index=1,
number=2,
type=5,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="playback_speed",
full_name="spotify.player.proto.transfer.Playback.playback_speed",
index=2,
number=3,
type=1,
cpp_type=5,
label=1,
has_default_value=False,
default_value=float(0),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="is_paused",
full_name="spotify.player.proto.transfer.Playback.is_paused",
index=3,
number=4,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="current_track",
full_name="spotify.player.proto.transfer.Playback.current_track",
index=4,
number=5,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=71,
serialized_end=236,
)
_PLAYBACK.fields_by_name[
"current_track"].message_type = context__track__pb2._CONTEXTTRACK
DESCRIPTOR.message_types_by_name["Playback"] = _PLAYBACK
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Playback = _reflection.GeneratedProtocolMessageType(
"Playback",
(_message.Message, ),
{
"DESCRIPTOR": _PLAYBACK,
"__module__": "playback_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.transfer.Playback)
},
)
_sym_db.RegisterMessage(Playback)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,460 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: playlist_annotate3.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import enum_type_wrapper
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="playlist_annotate3.proto",
package="spotify_playlist_annotate3.proto",
syntax="proto2",
serialized_options=b"\n\036com.spotify.playlist_annotate3H\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x18playlist_annotate3.proto\x12 spotify_playlist_annotate3.proto"a\n\x0fTakedownRequest\x12N\n\x12\x61\x62use_report_state\x18\x01 \x01(\x0e\x32\x32.spotify_playlist_annotate3.proto.AbuseReportState"9\n\x0f\x41nnotateRequest\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x11\n\timage_uri\x18\x02 \x01(\t"5\n\x11TranscodedPicture\x12\x13\n\x0btarget_name\x18\x01 \x01(\t\x12\x0b\n\x03uri\x18\x02 \x01(\t"\xf4\x02\n\x12PlaylistAnnotation\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x0f\n\x07picture\x18\x02 \x01(\t\x12i\n\x1a\x64\x65precated_render_features\x18\x03 \x01(\x0e\x32\x30.spotify_playlist_annotate3.proto.RenderFeatures:\x0fNORMAL_FEATURESB\x02\x18\x01\x12O\n\x12transcoded_picture\x18\x04 \x03(\x0b\x32\x33.spotify_playlist_annotate3.proto.TranscodedPicture\x12(\n\x1ais_abuse_reporting_enabled\x18\x06 \x01(\x08:\x04true\x12R\n\x12\x61\x62use_report_state\x18\x07 \x01(\x0e\x32\x32.spotify_playlist_annotate3.proto.AbuseReportState:\x02OK*<\n\x0eRenderFeatures\x12\x13\n\x0fNORMAL_FEATURES\x10\x01\x12\x15\n\x11\x45XTENDED_FEATURES\x10\x02**\n\x10\x41\x62useReportState\x12\x06\n\x02OK\x10\x00\x12\x0e\n\nTAKEN_DOWN\x10\x01\x42"\n\x1e\x63om.spotify.playlist_annotate3H\x02',
)
_RENDERFEATURES = _descriptor.EnumDescriptor(
name="RenderFeatures",
full_name="spotify_playlist_annotate3.proto.RenderFeatures",
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name="NORMAL_FEATURES",
index=0,
number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="EXTENDED_FEATURES",
index=1,
number=2,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
],
containing_type=None,
serialized_options=None,
serialized_start=650,
serialized_end=710,
)
_sym_db.RegisterEnumDescriptor(_RENDERFEATURES)
RenderFeatures = enum_type_wrapper.EnumTypeWrapper(_RENDERFEATURES)
_ABUSEREPORTSTATE = _descriptor.EnumDescriptor(
name="AbuseReportState",
full_name="spotify_playlist_annotate3.proto.AbuseReportState",
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name="OK",
index=0,
number=0,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="TAKEN_DOWN",
index=1,
number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
],
containing_type=None,
serialized_options=None,
serialized_start=712,
serialized_end=754,
)
_sym_db.RegisterEnumDescriptor(_ABUSEREPORTSTATE)
AbuseReportState = enum_type_wrapper.EnumTypeWrapper(_ABUSEREPORTSTATE)
NORMAL_FEATURES = 1
EXTENDED_FEATURES = 2
OK = 0
TAKEN_DOWN = 1
_TAKEDOWNREQUEST = _descriptor.Descriptor(
name="TakedownRequest",
full_name="spotify_playlist_annotate3.proto.TakedownRequest",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="abuse_report_state",
full_name=
"spotify_playlist_annotate3.proto.TakedownRequest.abuse_report_state",
index=0,
number=1,
type=14,
cpp_type=8,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=62,
serialized_end=159,
)
_ANNOTATEREQUEST = _descriptor.Descriptor(
name="AnnotateRequest",
full_name="spotify_playlist_annotate3.proto.AnnotateRequest",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="description",
full_name=
"spotify_playlist_annotate3.proto.AnnotateRequest.description",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="image_uri",
full_name=
"spotify_playlist_annotate3.proto.AnnotateRequest.image_uri",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=161,
serialized_end=218,
)
_TRANSCODEDPICTURE = _descriptor.Descriptor(
name="TranscodedPicture",
full_name="spotify_playlist_annotate3.proto.TranscodedPicture",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="target_name",
full_name=
"spotify_playlist_annotate3.proto.TranscodedPicture.target_name",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="uri",
full_name="spotify_playlist_annotate3.proto.TranscodedPicture.uri",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=220,
serialized_end=273,
)
_PLAYLISTANNOTATION = _descriptor.Descriptor(
name="PlaylistAnnotation",
full_name="spotify_playlist_annotate3.proto.PlaylistAnnotation",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="description",
full_name=
"spotify_playlist_annotate3.proto.PlaylistAnnotation.description",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="picture",
full_name=
"spotify_playlist_annotate3.proto.PlaylistAnnotation.picture",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="deprecated_render_features",
full_name=
"spotify_playlist_annotate3.proto.PlaylistAnnotation.deprecated_render_features",
index=2,
number=3,
type=14,
cpp_type=8,
label=1,
has_default_value=True,
default_value=1,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=b"\030\001",
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="transcoded_picture",
full_name=
"spotify_playlist_annotate3.proto.PlaylistAnnotation.transcoded_picture",
index=3,
number=4,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="is_abuse_reporting_enabled",
full_name=
"spotify_playlist_annotate3.proto.PlaylistAnnotation.is_abuse_reporting_enabled",
index=4,
number=6,
type=8,
cpp_type=7,
label=1,
has_default_value=True,
default_value=True,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="abuse_report_state",
full_name=
"spotify_playlist_annotate3.proto.PlaylistAnnotation.abuse_report_state",
index=5,
number=7,
type=14,
cpp_type=8,
label=1,
has_default_value=True,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=276,
serialized_end=648,
)
_TAKEDOWNREQUEST.fields_by_name[
"abuse_report_state"].enum_type = _ABUSEREPORTSTATE
_PLAYLISTANNOTATION.fields_by_name[
"deprecated_render_features"].enum_type = _RENDERFEATURES
_PLAYLISTANNOTATION.fields_by_name[
"transcoded_picture"].message_type = _TRANSCODEDPICTURE
_PLAYLISTANNOTATION.fields_by_name[
"abuse_report_state"].enum_type = _ABUSEREPORTSTATE
DESCRIPTOR.message_types_by_name["TakedownRequest"] = _TAKEDOWNREQUEST
DESCRIPTOR.message_types_by_name["AnnotateRequest"] = _ANNOTATEREQUEST
DESCRIPTOR.message_types_by_name["TranscodedPicture"] = _TRANSCODEDPICTURE
DESCRIPTOR.message_types_by_name["PlaylistAnnotation"] = _PLAYLISTANNOTATION
DESCRIPTOR.enum_types_by_name["RenderFeatures"] = _RENDERFEATURES
DESCRIPTOR.enum_types_by_name["AbuseReportState"] = _ABUSEREPORTSTATE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
TakedownRequest = _reflection.GeneratedProtocolMessageType(
"TakedownRequest",
(_message.Message, ),
{
"DESCRIPTOR": _TAKEDOWNREQUEST,
"__module__": "playlist_annotate3_pb2"
# @@protoc_insertion_point(class_scope:spotify_playlist_annotate3.proto.TakedownRequest)
},
)
_sym_db.RegisterMessage(TakedownRequest)
AnnotateRequest = _reflection.GeneratedProtocolMessageType(
"AnnotateRequest",
(_message.Message, ),
{
"DESCRIPTOR": _ANNOTATEREQUEST,
"__module__": "playlist_annotate3_pb2"
# @@protoc_insertion_point(class_scope:spotify_playlist_annotate3.proto.AnnotateRequest)
},
)
_sym_db.RegisterMessage(AnnotateRequest)
TranscodedPicture = _reflection.GeneratedProtocolMessageType(
"TranscodedPicture",
(_message.Message, ),
{
"DESCRIPTOR": _TRANSCODEDPICTURE,
"__module__": "playlist_annotate3_pb2"
# @@protoc_insertion_point(class_scope:spotify_playlist_annotate3.proto.TranscodedPicture)
},
)
_sym_db.RegisterMessage(TranscodedPicture)
PlaylistAnnotation = _reflection.GeneratedProtocolMessageType(
"PlaylistAnnotation",
(_message.Message, ),
{
"DESCRIPTOR": _PLAYLISTANNOTATION,
"__module__": "playlist_annotate3_pb2"
# @@protoc_insertion_point(class_scope:spotify_playlist_annotate3.proto.PlaylistAnnotation)
},
)
_sym_db.RegisterMessage(PlaylistAnnotation)
DESCRIPTOR._options = None
_PLAYLISTANNOTATION.fields_by_name[
"deprecated_render_features"]._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: pubsub.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='pubsub.proto',
package='spotify',
syntax='proto2',
serialized_options=b'\n\013com.spotify',
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x0cpubsub.proto\x12\x07spotify\"@\n\x0cSubscription\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12\x0e\n\x06\x65xpiry\x18\x02 \x01(\x05\x12\x13\n\x0bstatus_code\x18\x03 \x01(\x05\x42\r\n\x0b\x63om.spotify'
)
_SUBSCRIPTION = _descriptor.Descriptor(
name='Subscription',
full_name='spotify.Subscription',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='uri',
full_name='spotify.Subscription.uri',
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode('utf-8'),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='expiry',
full_name='spotify.Subscription.expiry',
index=1,
number=2,
type=5,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='status_code',
full_name='spotify.Subscription.status_code',
index=2,
number=3,
type=5,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[],
serialized_start=25,
serialized_end=89,
)
DESCRIPTOR.message_types_by_name['Subscription'] = _SUBSCRIPTION
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Subscription = _reflection.GeneratedProtocolMessageType(
'Subscription',
(_message.Message, ),
{
'DESCRIPTOR': _SUBSCRIPTION,
'__module__': 'pubsub_pb2'
# @@protoc_insertion_point(class_scope:spotify.Subscription)
})
_sym_db.RegisterMessage(Subscription)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: queue.proto
"""Generated protocol buffer code."""
import ContextTrack_pb2 as context__track__pb2
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="queue.proto",
package="spotify.player.proto.transfer",
syntax="proto2",
serialized_options=b"\n\024com.spotify.transferH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x0bqueue.proto\x12\x1dspotify.player.proto.transfer\x1a\x13\x63ontext_track.proto"U\n\x05Queue\x12\x32\n\x06tracks\x18\x01 \x03(\x0b\x32".spotify.player.proto.ContextTrack\x12\x18\n\x10is_playing_queue\x18\x02 \x01(\x08\x42\x18\n\x14\x63om.spotify.transferH\x02',
dependencies=[
context__track__pb2.DESCRIPTOR,
],
)
_QUEUE = _descriptor.Descriptor(
name="Queue",
full_name="spotify.player.proto.transfer.Queue",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="tracks",
full_name="spotify.player.proto.transfer.Queue.tracks",
index=0,
number=1,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="is_playing_queue",
full_name="spotify.player.proto.transfer.Queue.is_playing_queue",
index=1,
number=2,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=67,
serialized_end=152,
)
_QUEUE.fields_by_name[
"tracks"].message_type = context__track__pb2._CONTEXTTRACK
DESCRIPTOR.message_types_by_name["Queue"] = _QUEUE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Queue = _reflection.GeneratedProtocolMessageType(
"Queue",
(_message.Message, ),
{
"DESCRIPTOR": _QUEUE,
"__module__": "queue_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.transfer.Queue)
},
)
_sym_db.RegisterMessage(Queue)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,480 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: restrictions.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="restrictions.proto",
package="spotify.player.proto",
syntax="proto2",
serialized_options=b"\n\023com.spotify.contextH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x12restrictions.proto\x12\x14spotify.player.proto"\xbb\x07\n\x0cRestrictions\x12 \n\x18\x64isallow_pausing_reasons\x18\x01 \x03(\t\x12!\n\x19\x64isallow_resuming_reasons\x18\x02 \x03(\t\x12 \n\x18\x64isallow_seeking_reasons\x18\x03 \x03(\t\x12%\n\x1d\x64isallow_peeking_prev_reasons\x18\x04 \x03(\t\x12%\n\x1d\x64isallow_peeking_next_reasons\x18\x05 \x03(\t\x12&\n\x1e\x64isallow_skipping_prev_reasons\x18\x06 \x03(\t\x12&\n\x1e\x64isallow_skipping_next_reasons\x18\x07 \x03(\t\x12\x30\n(disallow_toggling_repeat_context_reasons\x18\x08 \x03(\t\x12.\n&disallow_toggling_repeat_track_reasons\x18\t \x03(\t\x12)\n!disallow_toggling_shuffle_reasons\x18\n \x03(\t\x12"\n\x1a\x64isallow_set_queue_reasons\x18\x0b \x03(\t\x12.\n&disallow_interrupting_playback_reasons\x18\x0c \x03(\t\x12.\n&disallow_transferring_playback_reasons\x18\r \x03(\t\x12\'\n\x1f\x64isallow_remote_control_reasons\x18\x0e \x03(\t\x12\x33\n+disallow_inserting_into_next_tracks_reasons\x18\x0f \x03(\t\x12\x36\n.disallow_inserting_into_context_tracks_reasons\x18\x10 \x03(\t\x12\x32\n*disallow_reordering_in_next_tracks_reasons\x18\x11 \x03(\t\x12\x35\n-disallow_reordering_in_context_tracks_reasons\x18\x12 \x03(\t\x12\x32\n*disallow_removing_from_next_tracks_reasons\x18\x13 \x03(\t\x12\x35\n-disallow_removing_from_context_tracks_reasons\x18\x14 \x03(\t\x12)\n!disallow_updating_context_reasons\x18\x15 \x03(\tB\x17\n\x13\x63om.spotify.contextH\x02',
)
_RESTRICTIONS = _descriptor.Descriptor(
name="Restrictions",
full_name="spotify.player.proto.Restrictions",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="disallow_pausing_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_pausing_reasons",
index=0,
number=1,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_resuming_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_resuming_reasons",
index=1,
number=2,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_seeking_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_seeking_reasons",
index=2,
number=3,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_peeking_prev_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_peeking_prev_reasons",
index=3,
number=4,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_peeking_next_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_peeking_next_reasons",
index=4,
number=5,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_skipping_prev_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_skipping_prev_reasons",
index=5,
number=6,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_skipping_next_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_skipping_next_reasons",
index=6,
number=7,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_toggling_repeat_context_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_toggling_repeat_context_reasons",
index=7,
number=8,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_toggling_repeat_track_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_toggling_repeat_track_reasons",
index=8,
number=9,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_toggling_shuffle_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_toggling_shuffle_reasons",
index=9,
number=10,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_set_queue_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_set_queue_reasons",
index=10,
number=11,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_interrupting_playback_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_interrupting_playback_reasons",
index=11,
number=12,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_transferring_playback_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_transferring_playback_reasons",
index=12,
number=13,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_remote_control_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_remote_control_reasons",
index=13,
number=14,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_inserting_into_next_tracks_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_inserting_into_next_tracks_reasons",
index=14,
number=15,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_inserting_into_context_tracks_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_inserting_into_context_tracks_reasons",
index=15,
number=16,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_reordering_in_next_tracks_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_reordering_in_next_tracks_reasons",
index=16,
number=17,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_reordering_in_context_tracks_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_reordering_in_context_tracks_reasons",
index=17,
number=18,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_removing_from_next_tracks_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_removing_from_next_tracks_reasons",
index=18,
number=19,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_removing_from_context_tracks_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_removing_from_context_tracks_reasons",
index=19,
number=20,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="disallow_updating_context_reasons",
full_name=
"spotify.player.proto.Restrictions.disallow_updating_context_reasons",
index=20,
number=21,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=45,
serialized_end=1000,
)
DESCRIPTOR.message_types_by_name["Restrictions"] = _RESTRICTIONS
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Restrictions = _reflection.GeneratedProtocolMessageType(
"Restrictions",
(_message.Message, ),
{
"DESCRIPTOR": _RESTRICTIONS,
"__module__": "restrictions_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.Restrictions)
},
)
_sym_db.RegisterMessage(Restrictions)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,149 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: session.proto
"""Generated protocol buffer code."""
import Context_pb2 as context__pb2
import ContextPlayerOptions_pb2 as context__player__options__pb2
import PlayOrigin_pb2 as play__origin__pb2
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="session.proto",
package="spotify.player.proto.transfer",
syntax="proto2",
serialized_options=b"\n\024com.spotify.transferH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\rsession.proto\x12\x1dspotify.player.proto.transfer\x1a\rcontext.proto\x1a\x1c\x63ontext_player_options.proto\x1a\x11play_origin.proto"\xd3\x01\n\x07Session\x12\x35\n\x0bplay_origin\x18\x01 \x01(\x0b\x32 .spotify.player.proto.PlayOrigin\x12.\n\x07\x63ontext\x18\x02 \x01(\x0b\x32\x1d.spotify.player.proto.Context\x12\x13\n\x0b\x63urrent_uid\x18\x03 \x01(\t\x12L\n\x10option_overrides\x18\x04 \x01(\x0b\x32\x32.spotify.player.proto.ContextPlayerOptionOverridesB\x18\n\x14\x63om.spotify.transferH\x02',
dependencies=[
context__pb2.DESCRIPTOR,
context__player__options__pb2.DESCRIPTOR,
play__origin__pb2.DESCRIPTOR,
],
)
_SESSION = _descriptor.Descriptor(
name="Session",
full_name="spotify.player.proto.transfer.Session",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="play_origin",
full_name="spotify.player.proto.transfer.Session.play_origin",
index=0,
number=1,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="context",
full_name="spotify.player.proto.transfer.Session.context",
index=1,
number=2,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="current_uid",
full_name="spotify.player.proto.transfer.Session.current_uid",
index=2,
number=3,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="option_overrides",
full_name="spotify.player.proto.transfer.Session.option_overrides",
index=3,
number=4,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=113,
serialized_end=324,
)
_SESSION.fields_by_name[
"play_origin"].message_type = play__origin__pb2._PLAYORIGIN
_SESSION.fields_by_name["context"].message_type = context__pb2._CONTEXT
_SESSION.fields_by_name[
"option_overrides"].message_type = context__player__options__pb2._CONTEXTPLAYEROPTIONOVERRIDES
DESCRIPTOR.message_types_by_name["Session"] = _SESSION
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Session = _reflection.GeneratedProtocolMessageType(
"Session",
(_message.Message, ),
{
"DESCRIPTOR": _SESSION,
"__module__": "session_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.transfer.Session)
},
)
_sym_db.RegisterMessage(Session)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,154 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: storage-resolve.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='storage-resolve.proto',
package='spotify.download.proto',
syntax='proto3',
serialized_options=b'\n\023com.spotify.storageH\002',
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x15storage-resolve.proto\x12\x16spotify.download.proto\"\xaf\x01\n\x16StorageResolveResponse\x12\x45\n\x06result\x18\x01 \x01(\x0e\x32\x35.spotify.download.proto.StorageResolveResponse.Result\x12\x0e\n\x06\x63\x64nurl\x18\x02 \x03(\t\x12\x0e\n\x06\x66ileid\x18\x04 \x01(\x0c\".\n\x06Result\x12\x07\n\x03\x43\x44N\x10\x00\x12\x0b\n\x07STORAGE\x10\x01\x12\x0e\n\nRESTRICTED\x10\x03\x42\x17\n\x13\x63om.spotify.storageH\x02\x62\x06proto3'
)
_STORAGERESOLVERESPONSE_RESULT = _descriptor.EnumDescriptor(
name='Result',
full_name='spotify.download.proto.StorageResolveResponse.Result',
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name='CDN',
index=0,
number=0,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='STORAGE',
index=1,
number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='RESTRICTED',
index=2,
number=3,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
],
containing_type=None,
serialized_options=None,
serialized_start=179,
serialized_end=225,
)
_sym_db.RegisterEnumDescriptor(_STORAGERESOLVERESPONSE_RESULT)
_STORAGERESOLVERESPONSE = _descriptor.Descriptor(
name='StorageResolveResponse',
full_name='spotify.download.proto.StorageResolveResponse',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='result',
full_name='spotify.download.proto.StorageResolveResponse.result',
index=0,
number=1,
type=14,
cpp_type=8,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='cdnurl',
full_name='spotify.download.proto.StorageResolveResponse.cdnurl',
index=1,
number=2,
type=9,
cpp_type=9,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='fileid',
full_name='spotify.download.proto.StorageResolveResponse.fileid',
index=2,
number=4,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[],
nested_types=[],
enum_types=[
_STORAGERESOLVERESPONSE_RESULT,
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[],
serialized_start=50,
serialized_end=225,
)
_STORAGERESOLVERESPONSE.fields_by_name[
'result'].enum_type = _STORAGERESOLVERESPONSE_RESULT
_STORAGERESOLVERESPONSE_RESULT.containing_type = _STORAGERESOLVERESPONSE
DESCRIPTOR.message_types_by_name[
'StorageResolveResponse'] = _STORAGERESOLVERESPONSE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
StorageResolveResponse = _reflection.GeneratedProtocolMessageType(
'StorageResolveResponse',
(_message.Message, ),
{
'DESCRIPTOR': _STORAGERESOLVERESPONSE,
'__module__': 'storage_resolve_pb2'
# @@protoc_insertion_point(class_scope:spotify.download.proto.StorageResolveResponse)
})
_sym_db.RegisterMessage(StorageResolveResponse)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,174 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: transfer_state.proto
"""Generated protocol buffer code."""
import ContextPlayerOptions_pb2 as context__player__options__pb2
import Playback_pb2 as playback__pb2
import Queue_pb2 as queue__pb2
import Session_pb2 as session__pb2
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="transfer_state.proto",
package="spotify.player.proto.transfer",
syntax="proto2",
serialized_options=b"\n\024com.spotify.transferH\002",
create_key=_descriptor._internal_create_key,
serialized_pb=
b"\n\x14transfer_state.proto\x12\x1dspotify.player.proto.transfer\x1a\x1c\x63ontext_player_options.proto\x1a\x0eplayback.proto\x1a\rsession.proto\x1a\x0bqueue.proto\"\x99\x02\n\rTransferState\x12;\n\x07options\x18\x01 \x01(\x0b\x32*.spotify.player.proto.ContextPlayerOptions\x12\x39\n\x08playback\x18\x02 \x01(\x0b\x32'.spotify.player.proto.transfer.Playback\x12?\n\x0f\x63urrent_session\x18\x03 \x01(\x0b\x32&.spotify.player.proto.transfer.Session\x12\x33\n\x05queue\x18\x04 \x01(\x0b\x32$.spotify.player.proto.transfer.Queue\x12\x1a\n\x12\x63reation_timestamp\x18\x05 \x01(\x03\x42\x18\n\x14\x63om.spotify.transferH\x02",
dependencies=[
context__player__options__pb2.DESCRIPTOR,
playback__pb2.DESCRIPTOR,
session__pb2.DESCRIPTOR,
queue__pb2.DESCRIPTOR,
],
)
_TRANSFERSTATE = _descriptor.Descriptor(
name="TransferState",
full_name="spotify.player.proto.transfer.TransferState",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="options",
full_name="spotify.player.proto.transfer.TransferState.options",
index=0,
number=1,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="playback",
full_name="spotify.player.proto.transfer.TransferState.playback",
index=1,
number=2,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="current_session",
full_name=
"spotify.player.proto.transfer.TransferState.current_session",
index=2,
number=3,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="queue",
full_name="spotify.player.proto.transfer.TransferState.queue",
index=3,
number=4,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="creation_timestamp",
full_name=
"spotify.player.proto.transfer.TransferState.creation_timestamp",
index=4,
number=5,
type=3,
cpp_type=2,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto2",
extension_ranges=[],
oneofs=[],
serialized_start=130,
serialized_end=411,
)
_TRANSFERSTATE.fields_by_name[
"options"].message_type = context__player__options__pb2._CONTEXTPLAYEROPTIONS
_TRANSFERSTATE.fields_by_name[
"playback"].message_type = playback__pb2._PLAYBACK
_TRANSFERSTATE.fields_by_name[
"current_session"].message_type = session__pb2._SESSION
_TRANSFERSTATE.fields_by_name["queue"].message_type = queue__pb2._QUEUE
DESCRIPTOR.message_types_by_name["TransferState"] = _TRANSFERSTATE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
TransferState = _reflection.GeneratedProtocolMessageType(
"TransferState",
(_message.Message, ),
{
"DESCRIPTOR": _TRANSFERSTATE,
"__module__": "transfer_state_pb2"
# @@protoc_insertion_point(class_scope:spotify.player.proto.transfer.TransferState)
},
)
_sym_db.RegisterMessage(TransferState)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: spotify/login5/v3/client_info.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="spotify/login5/v3/client_info.proto",
package="spotify.login5.v3",
syntax="proto3",
serialized_options=b"\n\024com.spotify.login5v3",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n#spotify/login5/v3/client_info.proto\x12\x11spotify.login5.v3"2\n\nClientInfo\x12\x11\n\tclient_id\x18\x01 \x01(\t\x12\x11\n\tdevice_id\x18\x02 \x01(\tB\x16\n\x14\x63om.spotify.login5v3b\x06proto3',
)
_CLIENTINFO = _descriptor.Descriptor(
name="ClientInfo",
full_name="spotify.login5.v3.ClientInfo",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="client_id",
full_name="spotify.login5.v3.ClientInfo.client_id",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="device_id",
full_name="spotify.login5.v3.ClientInfo.device_id",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=58,
serialized_end=108,
)
DESCRIPTOR.message_types_by_name["ClientInfo"] = _CLIENTINFO
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
ClientInfo = _reflection.GeneratedProtocolMessageType(
"ClientInfo",
(_message.Message, ),
{
"DESCRIPTOR": _CLIENTINFO,
"__module__": "spotify.login5.v3.client_info_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.ClientInfo)
},
)
_sym_db.RegisterMessage(ClientInfo)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,972 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: spotify/login5/v3/login5.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import enum_type_wrapper
from spotify.login5.v3 import \
client_info_pb2 as spotify_dot_login5_dot_v3_dot_client__info__pb2
from spotify.login5.v3 import \
user_info_pb2 as spotify_dot_login5_dot_v3_dot_user__info__pb2
from spotify.login5.v3.challenges import \
code_pb2 as spotify_dot_login5_dot_v3_dot_challenges_dot_code__pb2
from spotify.login5.v3.challenges import \
hashcash_pb2 as spotify_dot_login5_dot_v3_dot_challenges_dot_hashcash__pb2
from spotify.login5.v3.credentials import \
credentials_pb2 as \
spotify_dot_login5_dot_v3_dot_credentials_dot_credentials__pb2
from spotify.login5.v3.identifiers import \
identifiers_pb2 as \
spotify_dot_login5_dot_v3_dot_identifiers_dot_identifiers__pb2
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="spotify/login5/v3/login5.proto",
package="spotify.login5.v3",
syntax="proto3",
serialized_options=b"\n\024com.spotify.login5v3",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\x1espotify/login5/v3/login5.proto\x12\x11spotify.login5.v3\x1a#spotify/login5/v3/client_info.proto\x1a!spotify/login5/v3/user_info.proto\x1a\'spotify/login5/v3/challenges/code.proto\x1a+spotify/login5/v3/challenges/hashcash.proto\x1a/spotify/login5/v3/credentials/credentials.proto\x1a/spotify/login5/v3/identifiers/identifiers.proto">\n\nChallenges\x12\x30\n\nchallenges\x18\x01 \x03(\x0b\x32\x1c.spotify.login5.v3.Challenge"\x89\x01\n\tChallenge\x12\x41\n\x08hashcash\x18\x01 \x01(\x0b\x32/.spotify.login5.v3.challenges.HashcashChallenge\x12\x39\n\x04\x63ode\x18\x02 \x01(\x0b\x32+.spotify.login5.v3.challenges.CodeChallenge"M\n\x12\x43hallengeSolutions\x12\x37\n\tsolutions\x18\x01 \x03(\x0b\x32$.spotify.login5.v3.ChallengeSolution"\x8f\x01\n\x11\x43hallengeSolution\x12@\n\x08hashcash\x18\x01 \x01(\x0b\x32..spotify.login5.v3.challenges.HashcashSolution\x12\x38\n\x04\x63ode\x18\x02 \x01(\x0b\x32*.spotify.login5.v3.challenges.CodeSolution"\xad\x05\n\x0cLoginRequest\x12\x32\n\x0b\x63lient_info\x18\x01 \x01(\x0b\x32\x1d.spotify.login5.v3.ClientInfo\x12\x15\n\rlogin_context\x18\x02 \x01(\x0c\x12\x42\n\x13\x63hallenge_solutions\x18\x03 \x01(\x0b\x32%.spotify.login5.v3.ChallengeSolutions\x12J\n\x11stored_credential\x18\x64 \x01(\x0b\x32/.spotify.login5.v3.credentials.StoredCredential\x12\x39\n\x08password\x18\x65 \x01(\x0b\x32\'.spotify.login5.v3.credentials.Password\x12Q\n\x15\x66\x61\x63\x65\x62ook_access_token\x18\x66 \x01(\x0b\x32\x32.spotify.login5.v3.credentials.FacebookAccessToken\x12@\n\x0cphone_number\x18g \x01(\x0b\x32*.spotify.login5.v3.identifiers.PhoneNumber\x12\x43\n\x0eone_time_token\x18h \x01(\x0b\x32+.spotify.login5.v3.credentials.OneTimeToken\x12U\n\x17parent_child_credential\x18i \x01(\x0b\x32\x34.spotify.login5.v3.credentials.ParentChildCredential\x12V\n\x18\x61pple_sign_in_credential\x18j \x01(\x0b\x32\x34.spotify.login5.v3.credentials.AppleSignInCredential"m\n\x07LoginOk\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x02 \x01(\t\x12\x19\n\x11stored_credential\x18\x03 \x01(\x0c\x12\x1f\n\x17\x61\x63\x63\x65ss_token_expires_in\x18\x04 \x01(\x05"\xf8\x02\n\rLoginResponse\x12&\n\x02ok\x18\x01 \x01(\x0b\x32\x1a.spotify.login5.v3.LoginOk\x12,\n\x05\x65rror\x18\x02 \x01(\x0e\x32\x1d.spotify.login5.v3.LoginError\x12\x31\n\nchallenges\x18\x03 \x01(\x0b\x32\x1d.spotify.login5.v3.Challenges\x12;\n\x08warnings\x18\x04 \x03(\x0e\x32).spotify.login5.v3.LoginResponse.Warnings\x12\x15\n\rlogin_context\x18\x05 \x01(\x0c\x12\x18\n\x10identifier_token\x18\x06 \x01(\t\x12.\n\tuser_info\x18\x07 \x01(\x0b\x32\x1b.spotify.login5.v3.UserInfo"@\n\x08Warnings\x12\x13\n\x0fUNKNOWN_WARNING\x10\x00\x12\x1f\n\x1b\x44\x45PRECATED_PROTOCOL_VERSION\x10\x01*\xd3\x01\n\nLoginError\x12\x11\n\rUNKNOWN_ERROR\x10\x00\x12\x17\n\x13INVALID_CREDENTIALS\x10\x01\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10\x02\x12\x1e\n\x1aUNSUPPORTED_LOGIN_PROTOCOL\x10\x03\x12\x0b\n\x07TIMEOUT\x10\x04\x12\x16\n\x12UNKNOWN_IDENTIFIER\x10\x05\x12\x15\n\x11TOO_MANY_ATTEMPTS\x10\x06\x12\x17\n\x13INVALID_PHONENUMBER\x10\x07\x12\x13\n\x0fTRY_AGAIN_LATER\x10\x08\x42\x16\n\x14\x63om.spotify.login5v3b\x06proto3',
dependencies=[
spotify_dot_login5_dot_v3_dot_client__info__pb2.DESCRIPTOR,
spotify_dot_login5_dot_v3_dot_user__info__pb2.DESCRIPTOR,
spotify_dot_login5_dot_v3_dot_challenges_dot_code__pb2.DESCRIPTOR,
spotify_dot_login5_dot_v3_dot_challenges_dot_hashcash__pb2.DESCRIPTOR,
spotify_dot_login5_dot_v3_dot_credentials_dot_credentials__pb2.
DESCRIPTOR,
spotify_dot_login5_dot_v3_dot_identifiers_dot_identifiers__pb2.
DESCRIPTOR,
],
)
_LOGINERROR = _descriptor.EnumDescriptor(
name="LoginError",
full_name="spotify.login5.v3.LoginError",
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name="UNKNOWN_ERROR",
index=0,
number=0,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="INVALID_CREDENTIALS",
index=1,
number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="BAD_REQUEST",
index=2,
number=2,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="UNSUPPORTED_LOGIN_PROTOCOL",
index=3,
number=3,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="TIMEOUT",
index=4,
number=4,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="UNKNOWN_IDENTIFIER",
index=5,
number=5,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="TOO_MANY_ATTEMPTS",
index=6,
number=6,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="INVALID_PHONENUMBER",
index=7,
number=7,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="TRY_AGAIN_LATER",
index=8,
number=8,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
],
containing_type=None,
serialized_options=None,
serialized_start=1917,
serialized_end=2128,
)
_sym_db.RegisterEnumDescriptor(_LOGINERROR)
LoginError = enum_type_wrapper.EnumTypeWrapper(_LOGINERROR)
UNKNOWN_ERROR = 0
INVALID_CREDENTIALS = 1
BAD_REQUEST = 2
UNSUPPORTED_LOGIN_PROTOCOL = 3
TIMEOUT = 4
UNKNOWN_IDENTIFIER = 5
TOO_MANY_ATTEMPTS = 6
INVALID_PHONENUMBER = 7
TRY_AGAIN_LATER = 8
_LOGINRESPONSE_WARNINGS = _descriptor.EnumDescriptor(
name="Warnings",
full_name="spotify.login5.v3.LoginResponse.Warnings",
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name="UNKNOWN_WARNING",
index=0,
number=0,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="DEPRECATED_PROTOCOL_VERSION",
index=1,
number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
],
containing_type=None,
serialized_options=None,
serialized_start=1850,
serialized_end=1914,
)
_sym_db.RegisterEnumDescriptor(_LOGINRESPONSE_WARNINGS)
_CHALLENGES = _descriptor.Descriptor(
name="Challenges",
full_name="spotify.login5.v3.Challenges",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="challenges",
full_name="spotify.login5.v3.Challenges.challenges",
index=0,
number=1,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=309,
serialized_end=371,
)
_CHALLENGE = _descriptor.Descriptor(
name="Challenge",
full_name="spotify.login5.v3.Challenge",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="hashcash",
full_name="spotify.login5.v3.Challenge.hashcash",
index=0,
number=1,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="code",
full_name="spotify.login5.v3.Challenge.code",
index=1,
number=2,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=374,
serialized_end=511,
)
_CHALLENGESOLUTIONS = _descriptor.Descriptor(
name="ChallengeSolutions",
full_name="spotify.login5.v3.ChallengeSolutions",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="solutions",
full_name="spotify.login5.v3.ChallengeSolutions.solutions",
index=0,
number=1,
type=11,
cpp_type=10,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=513,
serialized_end=590,
)
_CHALLENGESOLUTION = _descriptor.Descriptor(
name="ChallengeSolution",
full_name="spotify.login5.v3.ChallengeSolution",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="hashcash",
full_name="spotify.login5.v3.ChallengeSolution.hashcash",
index=0,
number=1,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="code",
full_name="spotify.login5.v3.ChallengeSolution.code",
index=1,
number=2,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=593,
serialized_end=736,
)
_LOGINREQUEST = _descriptor.Descriptor(
name="LoginRequest",
full_name="spotify.login5.v3.LoginRequest",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="client_info",
full_name="spotify.login5.v3.LoginRequest.client_info",
index=0,
number=1,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="login_context",
full_name="spotify.login5.v3.LoginRequest.login_context",
index=1,
number=2,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="challenge_solutions",
full_name="spotify.login5.v3.LoginRequest.challenge_solutions",
index=2,
number=3,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="stored_credential",
full_name="spotify.login5.v3.LoginRequest.stored_credential",
index=3,
number=100,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="password",
full_name="spotify.login5.v3.LoginRequest.password",
index=4,
number=101,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="facebook_access_token",
full_name="spotify.login5.v3.LoginRequest.facebook_access_token",
index=5,
number=102,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="phone_number",
full_name="spotify.login5.v3.LoginRequest.phone_number",
index=6,
number=103,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="one_time_token",
full_name="spotify.login5.v3.LoginRequest.one_time_token",
index=7,
number=104,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="parent_child_credential",
full_name="spotify.login5.v3.LoginRequest.parent_child_credential",
index=8,
number=105,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="apple_sign_in_credential",
full_name="spotify.login5.v3.LoginRequest.apple_sign_in_credential",
index=9,
number=106,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=739,
serialized_end=1424,
)
_LOGINOK = _descriptor.Descriptor(
name="LoginOk",
full_name="spotify.login5.v3.LoginOk",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="username",
full_name="spotify.login5.v3.LoginOk.username",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="access_token",
full_name="spotify.login5.v3.LoginOk.access_token",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="stored_credential",
full_name="spotify.login5.v3.LoginOk.stored_credential",
index=2,
number=3,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="access_token_expires_in",
full_name="spotify.login5.v3.LoginOk.access_token_expires_in",
index=3,
number=4,
type=5,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=1426,
serialized_end=1535,
)
_LOGINRESPONSE = _descriptor.Descriptor(
name="LoginResponse",
full_name="spotify.login5.v3.LoginResponse",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="ok",
full_name="spotify.login5.v3.LoginResponse.ok",
index=0,
number=1,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="error",
full_name="spotify.login5.v3.LoginResponse.error",
index=1,
number=2,
type=14,
cpp_type=8,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="challenges",
full_name="spotify.login5.v3.LoginResponse.challenges",
index=2,
number=3,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="warnings",
full_name="spotify.login5.v3.LoginResponse.warnings",
index=3,
number=4,
type=14,
cpp_type=8,
label=3,
has_default_value=False,
default_value=[],
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="login_context",
full_name="spotify.login5.v3.LoginResponse.login_context",
index=4,
number=5,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="identifier_token",
full_name="spotify.login5.v3.LoginResponse.identifier_token",
index=5,
number=6,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="user_info",
full_name="spotify.login5.v3.LoginResponse.user_info",
index=6,
number=7,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[
_LOGINRESPONSE_WARNINGS,
],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=1538,
serialized_end=1914,
)
_CHALLENGES.fields_by_name["challenges"].message_type = _CHALLENGE
_CHALLENGE.fields_by_name["hashcash"].message_type = (
spotify_dot_login5_dot_v3_dot_challenges_dot_hashcash__pb2.
_HASHCASHCHALLENGE)
_CHALLENGE.fields_by_name[
"code"].message_type = spotify_dot_login5_dot_v3_dot_challenges_dot_code__pb2._CODECHALLENGE
_CHALLENGESOLUTIONS.fields_by_name[
"solutions"].message_type = _CHALLENGESOLUTION
_CHALLENGESOLUTION.fields_by_name["hashcash"].message_type = (
spotify_dot_login5_dot_v3_dot_challenges_dot_hashcash__pb2.
_HASHCASHSOLUTION)
_CHALLENGESOLUTION.fields_by_name[
"code"].message_type = spotify_dot_login5_dot_v3_dot_challenges_dot_code__pb2._CODESOLUTION
_LOGINREQUEST.fields_by_name[
"client_info"].message_type = spotify_dot_login5_dot_v3_dot_client__info__pb2._CLIENTINFO
_LOGINREQUEST.fields_by_name[
"challenge_solutions"].message_type = _CHALLENGESOLUTIONS
_LOGINREQUEST.fields_by_name["stored_credential"].message_type = (
spotify_dot_login5_dot_v3_dot_credentials_dot_credentials__pb2.
_STOREDCREDENTIAL)
_LOGINREQUEST.fields_by_name["password"].message_type = (
spotify_dot_login5_dot_v3_dot_credentials_dot_credentials__pb2._PASSWORD)
_LOGINREQUEST.fields_by_name["facebook_access_token"].message_type = (
spotify_dot_login5_dot_v3_dot_credentials_dot_credentials__pb2.
_FACEBOOKACCESSTOKEN)
_LOGINREQUEST.fields_by_name["phone_number"].message_type = (
spotify_dot_login5_dot_v3_dot_identifiers_dot_identifiers__pb2._PHONENUMBER
)
_LOGINREQUEST.fields_by_name["one_time_token"].message_type = (
spotify_dot_login5_dot_v3_dot_credentials_dot_credentials__pb2.
_ONETIMETOKEN)
_LOGINREQUEST.fields_by_name["parent_child_credential"].message_type = (
spotify_dot_login5_dot_v3_dot_credentials_dot_credentials__pb2.
_PARENTCHILDCREDENTIAL)
_LOGINREQUEST.fields_by_name["apple_sign_in_credential"].message_type = (
spotify_dot_login5_dot_v3_dot_credentials_dot_credentials__pb2.
_APPLESIGNINCREDENTIAL)
_LOGINRESPONSE.fields_by_name["ok"].message_type = _LOGINOK
_LOGINRESPONSE.fields_by_name["error"].enum_type = _LOGINERROR
_LOGINRESPONSE.fields_by_name["challenges"].message_type = _CHALLENGES
_LOGINRESPONSE.fields_by_name["warnings"].enum_type = _LOGINRESPONSE_WARNINGS
_LOGINRESPONSE.fields_by_name[
"user_info"].message_type = spotify_dot_login5_dot_v3_dot_user__info__pb2._USERINFO
_LOGINRESPONSE_WARNINGS.containing_type = _LOGINRESPONSE
DESCRIPTOR.message_types_by_name["Challenges"] = _CHALLENGES
DESCRIPTOR.message_types_by_name["Challenge"] = _CHALLENGE
DESCRIPTOR.message_types_by_name["ChallengeSolutions"] = _CHALLENGESOLUTIONS
DESCRIPTOR.message_types_by_name["ChallengeSolution"] = _CHALLENGESOLUTION
DESCRIPTOR.message_types_by_name["LoginRequest"] = _LOGINREQUEST
DESCRIPTOR.message_types_by_name["LoginOk"] = _LOGINOK
DESCRIPTOR.message_types_by_name["LoginResponse"] = _LOGINRESPONSE
DESCRIPTOR.enum_types_by_name["LoginError"] = _LOGINERROR
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Challenges = _reflection.GeneratedProtocolMessageType(
"Challenges",
(_message.Message, ),
{
"DESCRIPTOR": _CHALLENGES,
"__module__": "spotify.login5.v3.login5_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.Challenges)
},
)
_sym_db.RegisterMessage(Challenges)
Challenge = _reflection.GeneratedProtocolMessageType(
"Challenge",
(_message.Message, ),
{
"DESCRIPTOR": _CHALLENGE,
"__module__": "spotify.login5.v3.login5_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.Challenge)
},
)
_sym_db.RegisterMessage(Challenge)
ChallengeSolutions = _reflection.GeneratedProtocolMessageType(
"ChallengeSolutions",
(_message.Message, ),
{
"DESCRIPTOR": _CHALLENGESOLUTIONS,
"__module__": "spotify.login5.v3.login5_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.ChallengeSolutions)
},
)
_sym_db.RegisterMessage(ChallengeSolutions)
ChallengeSolution = _reflection.GeneratedProtocolMessageType(
"ChallengeSolution",
(_message.Message, ),
{
"DESCRIPTOR": _CHALLENGESOLUTION,
"__module__": "spotify.login5.v3.login5_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.ChallengeSolution)
},
)
_sym_db.RegisterMessage(ChallengeSolution)
LoginRequest = _reflection.GeneratedProtocolMessageType(
"LoginRequest",
(_message.Message, ),
{
"DESCRIPTOR": _LOGINREQUEST,
"__module__": "spotify.login5.v3.login5_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.LoginRequest)
},
)
_sym_db.RegisterMessage(LoginRequest)
LoginOk = _reflection.GeneratedProtocolMessageType(
"LoginOk",
(_message.Message, ),
{
"DESCRIPTOR": _LOGINOK,
"__module__": "spotify.login5.v3.login5_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.LoginOk)
},
)
_sym_db.RegisterMessage(LoginOk)
LoginResponse = _reflection.GeneratedProtocolMessageType(
"LoginResponse",
(_message.Message, ),
{
"DESCRIPTOR": _LOGINRESPONSE,
"__module__": "spotify.login5.v3.login5_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.LoginResponse)
},
)
_sym_db.RegisterMessage(LoginResponse)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,263 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: spotify/login5/v3/user_info.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="spotify/login5/v3/user_info.proto",
package="spotify.login5.v3",
syntax="proto3",
serialized_options=b"\n\024com.spotify.login5v3",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n!spotify/login5/v3/user_info.proto\x12\x11spotify.login5.v3"\x97\x02\n\x08UserInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x16\n\x0e\x65mail_verified\x18\x03 \x01(\x08\x12\x11\n\tbirthdate\x18\x04 \x01(\t\x12\x32\n\x06gender\x18\x05 \x01(\x0e\x32".spotify.login5.v3.UserInfo.Gender\x12\x14\n\x0cphone_number\x18\x06 \x01(\t\x12\x1d\n\x15phone_number_verified\x18\x07 \x01(\x08\x12 \n\x18\x65mail_already_registered\x18\x08 \x01(\x08"8\n\x06Gender\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x08\n\x04MALE\x10\x01\x12\n\n\x06\x46\x45MALE\x10\x02\x12\x0b\n\x07NEUTRAL\x10\x03\x42\x16\n\x14\x63om.spotify.login5v3b\x06proto3',
)
_USERINFO_GENDER = _descriptor.EnumDescriptor(
name="Gender",
full_name="spotify.login5.v3.UserInfo.Gender",
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name="UNKNOWN",
index=0,
number=0,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="MALE",
index=1,
number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="FEMALE",
index=2,
number=2,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="NEUTRAL",
index=3,
number=3,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
],
containing_type=None,
serialized_options=None,
serialized_start=280,
serialized_end=336,
)
_sym_db.RegisterEnumDescriptor(_USERINFO_GENDER)
_USERINFO = _descriptor.Descriptor(
name="UserInfo",
full_name="spotify.login5.v3.UserInfo",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="name",
full_name="spotify.login5.v3.UserInfo.name",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="email",
full_name="spotify.login5.v3.UserInfo.email",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="email_verified",
full_name="spotify.login5.v3.UserInfo.email_verified",
index=2,
number=3,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="birthdate",
full_name="spotify.login5.v3.UserInfo.birthdate",
index=3,
number=4,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="gender",
full_name="spotify.login5.v3.UserInfo.gender",
index=4,
number=5,
type=14,
cpp_type=8,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="phone_number",
full_name="spotify.login5.v3.UserInfo.phone_number",
index=5,
number=6,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="phone_number_verified",
full_name="spotify.login5.v3.UserInfo.phone_number_verified",
index=6,
number=7,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="email_already_registered",
full_name="spotify.login5.v3.UserInfo.email_already_registered",
index=7,
number=8,
type=8,
cpp_type=7,
label=1,
has_default_value=False,
default_value=False,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[
_USERINFO_GENDER,
],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=57,
serialized_end=336,
)
_USERINFO.fields_by_name["gender"].enum_type = _USERINFO_GENDER
_USERINFO_GENDER.containing_type = _USERINFO
DESCRIPTOR.message_types_by_name["UserInfo"] = _USERINFO
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
UserInfo = _reflection.GeneratedProtocolMessageType(
"UserInfo",
(_message.Message, ),
{
"DESCRIPTOR": _USERINFO,
"__module__": "spotify.login5.v3.user_info_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.UserInfo)
},
)
_sym_db.RegisterMessage(UserInfo)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,224 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: spotify/login5/v3/challenges/code.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="spotify/login5/v3/challenges/code.proto",
package="spotify.login5.v3.challenges",
syntax="proto3",
serialized_options=b"\n\024com.spotify.login5v3",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n\'spotify/login5/v3/challenges/code.proto\x12\x1cspotify.login5.v3.challenges"\xbc\x01\n\rCodeChallenge\x12\x42\n\x06method\x18\x01 \x01(\x0e\x32\x32.spotify.login5.v3.challenges.CodeChallenge.Method\x12\x13\n\x0b\x63ode_length\x18\x02 \x01(\x05\x12\x12\n\nexpires_in\x18\x03 \x01(\x05\x12\x1e\n\x16\x63\x61nonical_phone_number\x18\x04 \x01(\t"\x1e\n\x06Method\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03SMS\x10\x01"\x1c\n\x0c\x43odeSolution\x12\x0c\n\x04\x63ode\x18\x01 \x01(\tB\x16\n\x14\x63om.spotify.login5v3b\x06proto3',
)
_CODECHALLENGE_METHOD = _descriptor.EnumDescriptor(
name="Method",
full_name="spotify.login5.v3.challenges.CodeChallenge.Method",
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name="UNKNOWN",
index=0,
number=0,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.EnumValueDescriptor(
name="SMS",
index=1,
number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key,
),
],
containing_type=None,
serialized_options=None,
serialized_start=232,
serialized_end=262,
)
_sym_db.RegisterEnumDescriptor(_CODECHALLENGE_METHOD)
_CODECHALLENGE = _descriptor.Descriptor(
name="CodeChallenge",
full_name="spotify.login5.v3.challenges.CodeChallenge",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="method",
full_name="spotify.login5.v3.challenges.CodeChallenge.method",
index=0,
number=1,
type=14,
cpp_type=8,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="code_length",
full_name="spotify.login5.v3.challenges.CodeChallenge.code_length",
index=1,
number=2,
type=5,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="expires_in",
full_name="spotify.login5.v3.challenges.CodeChallenge.expires_in",
index=2,
number=3,
type=5,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="canonical_phone_number",
full_name=
"spotify.login5.v3.challenges.CodeChallenge.canonical_phone_number",
index=3,
number=4,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[
_CODECHALLENGE_METHOD,
],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=74,
serialized_end=262,
)
_CODESOLUTION = _descriptor.Descriptor(
name="CodeSolution",
full_name="spotify.login5.v3.challenges.CodeSolution",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="code",
full_name="spotify.login5.v3.challenges.CodeSolution.code",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=264,
serialized_end=292,
)
_CODECHALLENGE.fields_by_name["method"].enum_type = _CODECHALLENGE_METHOD
_CODECHALLENGE_METHOD.containing_type = _CODECHALLENGE
DESCRIPTOR.message_types_by_name["CodeChallenge"] = _CODECHALLENGE
DESCRIPTOR.message_types_by_name["CodeSolution"] = _CODESOLUTION
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
CodeChallenge = _reflection.GeneratedProtocolMessageType(
"CodeChallenge",
(_message.Message, ),
{
"DESCRIPTOR": _CODECHALLENGE,
"__module__": "spotify.login5.v3.challenges.code_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.challenges.CodeChallenge)
},
)
_sym_db.RegisterMessage(CodeChallenge)
CodeSolution = _reflection.GeneratedProtocolMessageType(
"CodeSolution",
(_message.Message, ),
{
"DESCRIPTOR": _CODESOLUTION,
"__module__": "spotify.login5.v3.challenges.code_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.challenges.CodeSolution)
},
)
_sym_db.RegisterMessage(CodeSolution)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,176 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: spotify/login5/v3/challenges/hashcash.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import \
duration_pb2 as google_dot_protobuf_dot_duration__pb2
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="spotify/login5/v3/challenges/hashcash.proto",
package="spotify.login5.v3.challenges",
syntax="proto3",
serialized_options=b"\n\024com.spotify.login5v3",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n+spotify/login5/v3/challenges/hashcash.proto\x12\x1cspotify.login5.v3.challenges\x1a\x1egoogle/protobuf/duration.proto"3\n\x11HashcashChallenge\x12\x0e\n\x06prefix\x18\x01 \x01(\x0c\x12\x0e\n\x06length\x18\x02 \x01(\x05"O\n\x10HashcashSolution\x12\x0e\n\x06suffix\x18\x01 \x01(\x0c\x12+\n\x08\x64uration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationB\x16\n\x14\x63om.spotify.login5v3b\x06proto3',
dependencies=[
google_dot_protobuf_dot_duration__pb2.DESCRIPTOR,
],
)
_HASHCASHCHALLENGE = _descriptor.Descriptor(
name="HashcashChallenge",
full_name="spotify.login5.v3.challenges.HashcashChallenge",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="prefix",
full_name="spotify.login5.v3.challenges.HashcashChallenge.prefix",
index=0,
number=1,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="length",
full_name="spotify.login5.v3.challenges.HashcashChallenge.length",
index=1,
number=2,
type=5,
cpp_type=1,
label=1,
has_default_value=False,
default_value=0,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=109,
serialized_end=160,
)
_HASHCASHSOLUTION = _descriptor.Descriptor(
name="HashcashSolution",
full_name="spotify.login5.v3.challenges.HashcashSolution",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="suffix",
full_name="spotify.login5.v3.challenges.HashcashSolution.suffix",
index=0,
number=1,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="duration",
full_name="spotify.login5.v3.challenges.HashcashSolution.duration",
index=1,
number=2,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=162,
serialized_end=241,
)
_HASHCASHSOLUTION.fields_by_name[
"duration"].message_type = google_dot_protobuf_dot_duration__pb2._DURATION
DESCRIPTOR.message_types_by_name["HashcashChallenge"] = _HASHCASHCHALLENGE
DESCRIPTOR.message_types_by_name["HashcashSolution"] = _HASHCASHSOLUTION
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
HashcashChallenge = _reflection.GeneratedProtocolMessageType(
"HashcashChallenge",
(_message.Message, ),
{
"DESCRIPTOR": _HASHCASHCHALLENGE,
"__module__": "spotify.login5.v3.challenges.hashcash_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.challenges.HashcashChallenge)
},
)
_sym_db.RegisterMessage(HashcashChallenge)
HashcashSolution = _reflection.GeneratedProtocolMessageType(
"HashcashSolution",
(_message.Message, ),
{
"DESCRIPTOR": _HASHCASHSOLUTION,
"__module__": "spotify.login5.v3.challenges.hashcash_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.challenges.HashcashSolution)
},
)
_sym_db.RegisterMessage(HashcashSolution)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,483 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: spotify/login5/v3/credentials/credentials.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="spotify/login5/v3/credentials/credentials.proto",
package="spotify.login5.v3.credentials",
syntax="proto3",
serialized_options=b"\n\024com.spotify.login5v3",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n/spotify/login5/v3/credentials/credentials.proto\x12\x1dspotify.login5.v3.credentials"2\n\x10StoredCredential\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c"9\n\x08Password\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08password\x18\x02 \x01(\t\x12\x0f\n\x07padding\x18\x03 \x01(\x0c";\n\x13\x46\x61\x63\x65\x62ookAccessToken\x12\x0e\n\x06\x66\x62_uid\x18\x01 \x01(\t\x12\x14\n\x0c\x61\x63\x63\x65ss_token\x18\x02 \x01(\t"\x1d\n\x0cOneTimeToken\x12\r\n\x05token\x18\x01 \x01(\t"|\n\x15ParentChildCredential\x12\x10\n\x08\x63hild_id\x18\x01 \x01(\t\x12Q\n\x18parent_stored_credential\x18\x02 \x01(\x0b\x32/.spotify.login5.v3.credentials.StoredCredential"S\n\x15\x41ppleSignInCredential\x12\x11\n\tauth_code\x18\x01 \x01(\t\x12\x14\n\x0credirect_uri\x18\x02 \x01(\t\x12\x11\n\tbundle_id\x18\x03 \x01(\tB\x16\n\x14\x63om.spotify.login5v3b\x06proto3',
)
_STOREDCREDENTIAL = _descriptor.Descriptor(
name="StoredCredential",
full_name="spotify.login5.v3.credentials.StoredCredential",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="username",
full_name="spotify.login5.v3.credentials.StoredCredential.username",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="data",
full_name="spotify.login5.v3.credentials.StoredCredential.data",
index=1,
number=2,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=82,
serialized_end=132,
)
_PASSWORD = _descriptor.Descriptor(
name="Password",
full_name="spotify.login5.v3.credentials.Password",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="id",
full_name="spotify.login5.v3.credentials.Password.id",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="password",
full_name="spotify.login5.v3.credentials.Password.password",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="padding",
full_name="spotify.login5.v3.credentials.Password.padding",
index=2,
number=3,
type=12,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"",
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=134,
serialized_end=191,
)
_FACEBOOKACCESSTOKEN = _descriptor.Descriptor(
name="FacebookAccessToken",
full_name="spotify.login5.v3.credentials.FacebookAccessToken",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="fb_uid",
full_name=
"spotify.login5.v3.credentials.FacebookAccessToken.fb_uid",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="access_token",
full_name=
"spotify.login5.v3.credentials.FacebookAccessToken.access_token",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=193,
serialized_end=252,
)
_ONETIMETOKEN = _descriptor.Descriptor(
name="OneTimeToken",
full_name="spotify.login5.v3.credentials.OneTimeToken",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="token",
full_name="spotify.login5.v3.credentials.OneTimeToken.token",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=254,
serialized_end=283,
)
_PARENTCHILDCREDENTIAL = _descriptor.Descriptor(
name="ParentChildCredential",
full_name="spotify.login5.v3.credentials.ParentChildCredential",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="child_id",
full_name=
"spotify.login5.v3.credentials.ParentChildCredential.child_id",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="parent_stored_credential",
full_name=
"spotify.login5.v3.credentials.ParentChildCredential.parent_stored_credential",
index=1,
number=2,
type=11,
cpp_type=10,
label=1,
has_default_value=False,
default_value=None,
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=285,
serialized_end=409,
)
_APPLESIGNINCREDENTIAL = _descriptor.Descriptor(
name="AppleSignInCredential",
full_name="spotify.login5.v3.credentials.AppleSignInCredential",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="auth_code",
full_name=
"spotify.login5.v3.credentials.AppleSignInCredential.auth_code",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="redirect_uri",
full_name=
"spotify.login5.v3.credentials.AppleSignInCredential.redirect_uri",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="bundle_id",
full_name=
"spotify.login5.v3.credentials.AppleSignInCredential.bundle_id",
index=2,
number=3,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=411,
serialized_end=494,
)
_PARENTCHILDCREDENTIAL.fields_by_name[
"parent_stored_credential"].message_type = _STOREDCREDENTIAL
DESCRIPTOR.message_types_by_name["StoredCredential"] = _STOREDCREDENTIAL
DESCRIPTOR.message_types_by_name["Password"] = _PASSWORD
DESCRIPTOR.message_types_by_name["FacebookAccessToken"] = _FACEBOOKACCESSTOKEN
DESCRIPTOR.message_types_by_name["OneTimeToken"] = _ONETIMETOKEN
DESCRIPTOR.message_types_by_name[
"ParentChildCredential"] = _PARENTCHILDCREDENTIAL
DESCRIPTOR.message_types_by_name[
"AppleSignInCredential"] = _APPLESIGNINCREDENTIAL
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
StoredCredential = _reflection.GeneratedProtocolMessageType(
"StoredCredential",
(_message.Message, ),
{
"DESCRIPTOR": _STOREDCREDENTIAL,
"__module__": "spotify.login5.v3.credentials.credentials_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.credentials.StoredCredential)
},
)
_sym_db.RegisterMessage(StoredCredential)
Password = _reflection.GeneratedProtocolMessageType(
"Password",
(_message.Message, ),
{
"DESCRIPTOR": _PASSWORD,
"__module__": "spotify.login5.v3.credentials.credentials_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.credentials.Password)
},
)
_sym_db.RegisterMessage(Password)
FacebookAccessToken = _reflection.GeneratedProtocolMessageType(
"FacebookAccessToken",
(_message.Message, ),
{
"DESCRIPTOR": _FACEBOOKACCESSTOKEN,
"__module__": "spotify.login5.v3.credentials.credentials_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.credentials.FacebookAccessToken)
},
)
_sym_db.RegisterMessage(FacebookAccessToken)
OneTimeToken = _reflection.GeneratedProtocolMessageType(
"OneTimeToken",
(_message.Message, ),
{
"DESCRIPTOR": _ONETIMETOKEN,
"__module__": "spotify.login5.v3.credentials.credentials_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.credentials.OneTimeToken)
},
)
_sym_db.RegisterMessage(OneTimeToken)
ParentChildCredential = _reflection.GeneratedProtocolMessageType(
"ParentChildCredential",
(_message.Message, ),
{
"DESCRIPTOR": _PARENTCHILDCREDENTIAL,
"__module__": "spotify.login5.v3.credentials.credentials_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.credentials.ParentChildCredential)
},
)
_sym_db.RegisterMessage(ParentChildCredential)
AppleSignInCredential = _reflection.GeneratedProtocolMessageType(
"AppleSignInCredential",
(_message.Message, ),
{
"DESCRIPTOR": _APPLESIGNINCREDENTIAL,
"__module__": "spotify.login5.v3.credentials.credentials_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.credentials.AppleSignInCredential)
},
)
_sym_db.RegisterMessage(AppleSignInCredential)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,119 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: spotify/login5/v3/identifiers/identifiers.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name="spotify/login5/v3/identifiers/identifiers.proto",
package="spotify.login5.v3.identifiers",
syntax="proto3",
serialized_options=b"\n\024com.spotify.login5v3",
create_key=_descriptor._internal_create_key,
serialized_pb=
b'\n/spotify/login5/v3/identifiers/identifiers.proto\x12\x1dspotify.login5.v3.identifiers"U\n\x0bPhoneNumber\x12\x0e\n\x06number\x18\x01 \x01(\t\x12\x18\n\x10iso_country_code\x18\x02 \x01(\t\x12\x1c\n\x14\x63ountry_calling_code\x18\x03 \x01(\tB\x16\n\x14\x63om.spotify.login5v3b\x06proto3',
)
_PHONENUMBER = _descriptor.Descriptor(
name="PhoneNumber",
full_name="spotify.login5.v3.identifiers.PhoneNumber",
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name="number",
full_name="spotify.login5.v3.identifiers.PhoneNumber.number",
index=0,
number=1,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="iso_country_code",
full_name=
"spotify.login5.v3.identifiers.PhoneNumber.iso_country_code",
index=1,
number=2,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
_descriptor.FieldDescriptor(
name="country_calling_code",
full_name=
"spotify.login5.v3.identifiers.PhoneNumber.country_calling_code",
index=2,
number=3,
type=9,
cpp_type=9,
label=1,
has_default_value=False,
default_value=b"".decode("utf-8"),
message_type=None,
enum_type=None,
containing_type=None,
is_extension=False,
extension_scope=None,
serialized_options=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
),
],
extensions=[],
nested_types=[],
enum_types=[],
serialized_options=None,
is_extendable=False,
syntax="proto3",
extension_ranges=[],
oneofs=[],
serialized_start=82,
serialized_end=167,
)
DESCRIPTOR.message_types_by_name["PhoneNumber"] = _PHONENUMBER
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
PhoneNumber = _reflection.GeneratedProtocolMessageType(
"PhoneNumber",
(_message.Message, ),
{
"DESCRIPTOR": _PHONENUMBER,
"__module__": "spotify.login5.v3.identifiers.identifiers_pb2"
# @@protoc_insertion_point(class_scope:spotify.login5.v3.identifiers.PhoneNumber)
},
)
_sym_db.RegisterMessage(PhoneNumber)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

View file

@ -0,0 +1,103 @@
from __future__ import annotations
import typing
if typing.TYPE_CHECKING:
from librespot.audio import AbsChunkedInputStream
from librespot.audio.format import SuperAudioFormat
from librespot.core import DealerClient, Session
from librespot.crypto import Packet
from librespot.mercury import MercuryClient
from librespot.proto import Metadata_pb2 as Metadata
class AudioDecrypt:
def decrypt_chunk(self, chunk_index: int, buffer: bytes):
raise NotImplementedError
def decrypt_time_ms(self):
raise NotImplementedError
class AudioQualityPicker:
def get_file(self,
files: typing.List[Metadata.AudioFile]) -> Metadata.AudioFile:
raise NotImplementedError
class Closeable:
def close(self) -> None:
raise NotImplementedError
class FeederException(Exception):
pass
class GeneralAudioStream:
def stream(self) -> AbsChunkedInputStream:
raise NotImplementedError
def codec(self) -> SuperAudioFormat:
raise NotImplementedError
def describe(self) -> str:
raise NotImplementedError
def decrypt_time_ms(self) -> int:
raise NotImplementedError
class GeneralWritableStream:
def write_chunk(self, buffer: bytearray, chunk_index: int, cached: bool):
raise NotImplementedError
class HaltListener:
def stream_read_halted(self, chunk: int, _time: int) -> None:
raise NotImplementedError
def stream_read_resumed(self, chunk: int, _time: int) -> None:
raise NotImplementedError
class MessageListener:
def on_message(self, uri: str, headers: typing.Dict[str, str],
payload: bytes):
raise NotImplementedError
class NoopAudioDecrypt(AudioDecrypt):
def decrypt_chunk(self, chunk_index: int, buffer: bytes):
return buffer
def decrypt_time_ms(self):
return 0
class PacketsReceiver:
def dispatch(self, packet: Packet):
raise NotImplementedError
class RequestListener:
def on_request(self, mid: str, pid: int, sender: str,
command: typing.Any) -> DealerClient.RequestResult:
raise NotImplementedError
class Runnable:
def run(self):
raise NotImplementedError
class SessionListener:
def session_closing(self, session: Session) -> None:
raise NotImplementedError
def session_changed(self, session: Session) -> None:
raise NotImplementedError
class SubListener:
def event(self, resp: MercuryClient.Response) -> None:
raise NotImplementedError

View file

@ -0,0 +1,117 @@
from Cryptodome import Random
import binascii
import math
def bytes_to_hex(buffer: bytes) -> str:
"""
Convert bytes to hex
Args:
buffer: Bytes to convert
Returns:
hex
"""
return binascii.hexlify(buffer).decode()
def hex_to_bytes(s: str) -> bytes:
return binascii.unhexlify(s)
def int_to_bytes(i: int):
"""
Convert an integer to a byte(s)
Args:
i: Integer to convert
Returns:
bytes
"""
width = i.bit_length()
width += 8 - ((width % 8) or 8)
fmt = '%%0%dx' % (width // 4)
return b"\x00" if i == 0 else binascii.unhexlify(fmt % i)
def random_hex_string(length: int):
buffer = Random.get_random_bytes(int(length / 2))
return bytes_to_hex(buffer)
class Base62:
standard_base = 256
target_base = 62
alphabet: bytes
lookup: bytearray
def __init__(self, alphabet: bytes):
self.alphabet = alphabet
self.create_lookup_table()
@staticmethod
def create_instance_with_inverted_character_set():
return Base62(Base62.CharacterSets.inverted)
def encode(self, message: bytes, length: int = -1):
indices = self.convert(message, self.standard_base, self.target_base,
length)
return self.translate(indices, self.alphabet)
def decode(self, encoded: bytes, length: int = -1):
prepared = self.translate(encoded, self.lookup)
return self.convert(prepared, self.target_base, self.standard_base,
length)
def translate(self, indices: bytes, dictionary: bytes):
translation = bytearray(len(indices))
for i in range(len(indices)):
translation[i] = dictionary[int.from_bytes(bytes([indices[i]]), "big")]
return translation
def convert(self, message: bytes, source_base: int, target_base: int,
length: int):
estimated_length = self.estimate_output_length(
len(message), source_base, target_base) if length == -1 else length
out = b""
source = message
while len(source) > 0:
quotient = b""
remainder = 0
for b in source:
accumulator = int(b & 0xff) + remainder * source_base
digit = int(
(accumulator - (accumulator % target_base)) / target_base)
remainder = int(accumulator % target_base)
if len(quotient) > 0 or digit > 0:
quotient += bytes([digit])
out += bytes([remainder])
source = quotient
if len(out) < estimated_length:
size = len(out)
for _ in range(estimated_length - size):
out += bytes([0])
return self.reverse(out)
if len(out) > estimated_length:
return self.reverse(out[:estimated_length])
return self.reverse(out)
def estimate_output_length(self, input_length: int, source_base: int,
target_base: int):
return int(
math.ceil((math.log(source_base) / math.log(target_base)) *
input_length))
def reverse(self, arr: bytes):
length = len(arr)
reversed_arr = bytearray(length)
for i in range(length):
reversed_arr[length - i - 1] = arr[i]
return bytes(reversed_arr)
def create_lookup_table(self):
self.lookup = bytearray(256)
for i in range(len(self.alphabet)):
self.lookup[self.alphabet[i]] = i & 0xff
class CharacterSets:
gmp = b'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
inverted = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

View file

@ -0,0 +1,345 @@
from __future__ import annotations
from Cryptodome.Cipher import AES
from Cryptodome.Hash import HMAC, SHA1
from Cryptodome.Util import Counter
from librespot import util, Version
from librespot.core import Session
from librespot.crypto import DiffieHellman
from librespot.proto import Connect_pb2 as Connect
from librespot.structure import Closeable, Runnable, SessionListener
import base64
import concurrent.futures
import copy
import io
import json
import logging
import random
import socket
import threading
import typing
import urllib.parse
import zeroconf
class ZeroconfServer(Closeable):
logger = logging.getLogger("Librespot:ZeroconfServer")
service = "_spotify-connect._tcp.local."
__connecting_username: typing.Union[str, None] = None
__connection_lock = threading.Condition()
__default_get_info_fields = {
"status": 101,
"statusString": "OK",
"spotifyError": 0,
"version": "2.7.1",
"libraryVersion": Version.version_name,
"accountReq": "PREMIUM",
"brandDisplayName": "kokarare1212",
"modelDisplayName": "librespot-python",
"voiceSupport": "NO",
"availability": "",
"productID": 0,
"tokenType": "default",
"groupStatus": "NONE",
"resolverVersion": "0",
"scope": "streaming,client-authorization-universal",
}
__default_successful_add_user = {
"status": 101,
"spotifyError": 0,
"statusString": "OK",
}
__eol = b"\r\n"
__max_port = 65536
__min_port = 1024
__runner: HttpRunner
__service_info: zeroconf.ServiceInfo
__session: typing.Union[Session, None] = None
__session_listeners: typing.List[SessionListener] = []
__zeroconf: zeroconf.Zeroconf
def __init__(self, inner: Inner, listen_port):
self.__inner = inner
self.__keys = DiffieHellman()
if listen_port == -1:
listen_port = random.randint(self.__min_port + 1, self.__max_port)
self.__runner = ZeroconfServer.HttpRunner(self, listen_port)
threading.Thread(target=self.__runner.run,
name="zeroconf-http-server").start()
self.__zeroconf = zeroconf.Zeroconf()
self.__service_info = zeroconf.ServiceInfo(
ZeroconfServer.service,
inner.device_name + "." + ZeroconfServer.service,
listen_port,
0,
0, {
"CPath": "/",
"VERSION": "1.0",
"STACK": "SP",
},
self.get_useful_hostname() + ".",
addresses=[
socket.inet_aton(
socket.gethostbyname(self.get_useful_hostname()))
])
self.__zeroconf.register_service(self.__service_info)
threading.Thread(target=self.__zeroconf.start,
name="zeroconf-multicast-dns-server").start()
def add_session_listener(self, listener: ZeroconfServer):
self.__session_listeners.append(listener)
def close(self) -> None:
self.__zeroconf.close()
self.__runner.close()
def close_session(self) -> None:
if self.__session is None:
return
for session_listener in self.__session_listeners:
session_listener.session_closing(self.__session)
self.__session.close()
self.__session = None
def get_useful_hostname(self) -> str:
host = socket.gethostname()
if host == "localhost":
pass
else:
return host
def handle_add_user(self, __socket: socket.socket, params: dict[str, str],
http_version: str) -> None:
username = params.get("userName")
if not username:
self.logger.error("Missing userName!")
return
blob_str = params.get("blob")
if not blob_str:
self.logger.error("Missing blob!")
return
client_key_str = params.get("clientKey")
if not client_key_str:
self.logger.error("Missing clientKey!")
with self.__connection_lock:
if username == self.__connecting_username:
self.logger.info(
"{} is already trying to connect.".format(username))
__socket.send(http_version.encode())
__socket.send(b" 403 Forbidden")
__socket.send(self.__eol)
__socket.send(self.__eol)
return
shared_key = util.int_to_bytes(
self.__keys.compute_shared_key(
base64.b64decode(client_key_str.encode())))
blob_bytes = base64.b64decode(blob_str)
iv = blob_bytes[:16]
encrypted = blob_bytes[16:len(blob_bytes) - 20]
checksum = blob_bytes[len(blob_bytes) - 20:]
sha1 = SHA1.new()
sha1.update(shared_key)
base_key = sha1.digest()[:16]
hmac = HMAC.new(base_key, digestmod=SHA1)
hmac.update(b"checksum")
checksum_key = hmac.digest()
hmac = HMAC.new(base_key, digestmod=SHA1)
hmac.update(b"encryption")
encryption_key = hmac.digest()
hmac = HMAC.new(checksum_key, digestmod=SHA1)
hmac.update(encrypted)
mac = hmac.digest()
if mac != checksum:
self.logger.error("Mac and checksum don't match!")
__socket.send(http_version.encode())
__socket.send(b" 400 Bad Request")
__socket.send(self.__eol)
__socket.send(self.__eol)
return
aes = AES.new(encryption_key[:16],
AES.MODE_CTR,
counter=Counter.new(128,
initial_value=int.from_bytes(
iv, "big")))
decrypted = aes.decrypt(encrypted)
self.close_session()
with self.__connection_lock:
self.__connecting_username = username
self.logger.info("Accepted new user from {}. [deviceId: {}]".format(
params.get("deviceName"), self.__inner.device_id))
response = json.dumps(self.__default_successful_add_user)
__socket.send(http_version.encode())
__socket.send(b" 200 OK")
__socket.send(self.__eol)
__socket.send(b"Content-Length: ")
__socket.send(str(len(response)).encode())
__socket.send(self.__eol)
__socket.send(self.__eol)
__socket.send(response.encode())
self.__session = Session.Builder(self.__inner.conf) \
.set_device_id(self.__inner.device_id) \
.set_device_name(self.__inner.device_name) \
.set_device_type(self.__inner.device_type) \
.set_preferred_locale(self.__inner.preferred_locale) \
.blob(username, decrypted) \
.create()
with self.__connection_lock:
self.__connecting_username = None
for session_listener in self.__session_listeners:
session_listener.session_changed(self.__session)
def handle_get_info(self, __socket: socket.socket,
http_version: str) -> None:
info = copy.deepcopy(self.__default_get_info_fields)
info["deviceID"] = self.__inner.device_id
info["remoteName"] = self.__inner.device_name
info["publicKey"] = base64.b64encode(
self.__keys.public_key_bytes()).decode()
info["deviceType"] = Connect.DeviceType.Name(self.__inner.device_type)
with self.__connection_lock:
info[
"activeUser"] = self.__connecting_username if self.__connecting_username is not None else self.__session.username(
) if self.has_valid_session() else ""
__socket.send(http_version.encode())
__socket.send(b" 200 OK")
__socket.send(self.__eol)
__socket.send(b"Content-Type: application/json")
__socket.send(self.__eol)
__socket.send(self.__eol)
__socket.send(json.dumps(info).encode())
def has_valid_session(self) -> bool:
valid = self.__session and self.__session.is_valid()
if not valid:
self.__session = None
return valid
def parse_path(self, path: str) -> dict[str, str]:
url = "https://host" + path
parsed = {}
params = urllib.parse.parse_qs(urllib.parse.urlparse(url).query)
for key, values in params.items():
for value in values:
parsed[key] = value
return parsed
def remove_session_listener(self, listener: SessionListener):
self.__session_listeners.remove(listener)
class Builder(Session.Builder):
listen_port: int = -1
def set_listen_port(self, listen_port: int):
self.listen_port = listen_port
return self
def create(self) -> ZeroconfServer:
return ZeroconfServer(
ZeroconfServer.Inner(self.device_type, self.device_name,
self.device_id, self.preferred_locale,
self.conf), self.listen_port)
class HttpRunner(Closeable, Runnable):
__should_stop = False
__socket: socket.socket
__worker = concurrent.futures.ThreadPoolExecutor()
__zeroconf_server: ZeroconfServer
def __init__(self, zeroconf_server: ZeroconfServer, port: int):
self.__socket = socket.socket()
self.__socket.bind((".".join(["0"] * 4), port))
self.__socket.listen(5)
self.__zeroconf_server = zeroconf_server
self.__zeroconf_server.logger.info(
"Zeroconf HTTP server started successfully on port {}!".format(
port))
def close(self) -> None:
pass
def run(self):
while not self.__should_stop:
__socket, address = self.__socket.accept()
def anonymous():
self.__handle(__socket)
__socket.close()
self.__worker.submit(anonymous)
def __handle(self, __socket: socket.socket) -> None:
request = io.BytesIO(__socket.recv(1024 * 1024))
request_line = request.readline().strip().split(b" ")
if len(request_line) != 3:
self.__zeroconf_server.logger.warning(
"Unexpected request line: {}".format(request_line))
method = request_line[0].decode()
path = request_line[1].decode()
http_version = request_line[2].decode()
headers = {}
while True:
header = request.readline().strip()
if not header:
break
split = header.split(b":")
headers[split[0].decode()] = split[1].strip().decode()
if not self.__zeroconf_server.has_valid_session():
self.__zeroconf_server.logger.debug(
"Handling request: {}, {}, {}, headers: {}".format(
method, path, http_version, headers))
params = {}
if method == "POST":
content_type = headers.get("Content-Type")
if content_type != "application/x-www-form-urlencoded":
self.__zeroconf_server.logger.error(
"Bad Content-Type: {}".format(content_type))
return
content_length_str = headers.get("Content-Length")
if content_length_str is None:
self.__zeroconf_server.logger.error(
"Missing Content-Length header!")
return
content_length = int(content_length_str)
body = request.read(content_length).decode()
pairs = body.split("&")
for pair in pairs:
split = pair.split("=")
params[urllib.parse.unquote(
split[0])] = urllib.parse.unquote(split[1])
else:
params = self.__zeroconf_server.parse_path(path)
action = params.get("action")
if action is None:
self.__zeroconf_server.logger.debug(
"Request is missing action.")
return
self.handle_request(__socket, http_version, action, params)
def handle_request(self, __socket: socket.socket, http_version: str,
action: str, params: dict[str, str]) -> None:
if action == "addUser":
if params is None:
raise RuntimeError
self.__zeroconf_server.handle_add_user(__socket, params,
http_version)
elif action == "getInfo":
self.__zeroconf_server.handle_get_info(__socket, http_version)
else:
self.__zeroconf_server.logger.warning(
"Unknown action: {}".format(action))
class Inner:
conf: typing.Final[Session.Configuration]
device_name: typing.Final[str]
device_id: typing.Final[str]
device_type: typing.Final[Connect.DeviceType]
preferred_locale: typing.Final[str]
def __init__(self, device_type: Connect.DeviceType, device_name: str,
device_id: str, preferred_locale: str,
conf: Session.Configuration):
self.conf = conf
self.device_name = device_name
self.device_id = util.random_hex_string(
40).lower() if not device_id else device_id
self.device_type = device_type
self.preferred_locale = preferred_locale