[Python-modules-commits] [pychromecast] 01/01: Import pychromecast_0.8.0.orig.tar.gz
Ruben Undheim
rubund-guest at moszumanska.debian.org
Sun Feb 5 08:37:32 UTC 2017
This is an automated email from the git hooks/post-receive script.
rubund-guest pushed a commit to branch upstream
in repository pychromecast.
commit f81705bf196140e297d90460c4c609d9e000a787
Author: Ruben Undheim <ruben.undheim at gmail.com>
Date: Sun Feb 5 09:31:59 2017 +0100
Import pychromecast_0.8.0.orig.tar.gz
---
.travis.yml | 1 +
README.rst | 6 +-
chromecast_protobuf/authority_keys.proto | 8 +-
chromecast_protobuf/cast_channel.proto | 28 +++-
chromecast_protobuf/logging.proto | 52 ++++++-
example.py => examples/blocking.py | 10 +-
examples/non_blocking.py | 82 +++++++++++
pychromecast/__init__.py | 221 ++++++++++------------------
pychromecast/authority_keys_pb2.py | 26 ++--
pychromecast/cast_channel_pb2.py | 163 ++++++++++++++-------
pychromecast/controllers/__init__.py | 8 +-
pychromecast/controllers/media.py | 59 +++++++-
pychromecast/controllers/youtube.py | 10 +-
pychromecast/discovery.py | 58 +++++---
pychromecast/logging_pb2.py | 198 +++++++++++++++++---------
pychromecast/socket_client.py | 237 ++++++++++++++++---------------
requirements.txt | 4 +-
setup.py | 2 +-
18 files changed, 741 insertions(+), 432 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index bf6e68e..28ad0de 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,7 @@ language: python
python:
- "2.7"
- "3.4"
+ - "3.5"
install:
- pip install -r requirements.txt
- pip install flake8 pylint
diff --git a/README.rst b/README.rst
index 6c528fe..e4ef4cf 100644
--- a/README.rst
+++ b/README.rst
@@ -40,10 +40,11 @@ How to use
>> import time
>> import pychromecast
- >> pychromecast.get_chromecasts_as_dict().keys()
+ >> chromecasts = pychromecast.get_chromecasts()
+ >> [cc.device.friendly_name for cc in chromecasts]
['Dev', 'Living Room', 'Den', 'Bedroom']
- >> cast = pychromecast.get_chromecast(friendly_name="Living Room")
+ >> cast = next(cc for cc in chromecasts if cc.device.friendly_name == "Living Room")
>> # Wait for cast device to be ready
>> cast.wait()
>> print(cast.device)
@@ -54,6 +55,7 @@ How to use
>> mc = cast.media_controller
>> mc.play_media('http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', 'video/mp4')
+ >> mc.block_until_active()
>> print(mc.status)
MediaStatus(current_time=42.458322, content_id=u'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', content_type=u'video/mp4', duration=596.474195, stream_type=u'BUFFERED', idle_reason=None, media_session_id=1, playback_rate=1, player_state=u'PLAYING', supported_media_commands=15, volume_level=1, volume_muted=False)
diff --git a/chromecast_protobuf/authority_keys.proto b/chromecast_protobuf/authority_keys.proto
index d33e9fd..791e831 100644
--- a/chromecast_protobuf/authority_keys.proto
+++ b/chromecast_protobuf/authority_keys.proto
@@ -1,13 +1,17 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
syntax = "proto2";
+
option optimize_for = LITE_RUNTIME;
-package extensions.core_api.cast_channel.proto;
+
+package extensions.api.cast_channel.proto;
+
message AuthorityKeys {
message Key {
required bytes fingerprint = 1;
required bytes public_key = 2;
}
repeated Key keys = 1;
-}
\ No newline at end of file
+}
diff --git a/chromecast_protobuf/cast_channel.proto b/chromecast_protobuf/cast_channel.proto
index 57174fd..098ecb7 100644
--- a/chromecast_protobuf/cast_channel.proto
+++ b/chromecast_protobuf/cast_channel.proto
@@ -1,9 +1,13 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
syntax = "proto2";
+
option optimize_for = LITE_RUNTIME;
-package extensions.core_api.cast_channel;
+
+package extensions.api.cast_channel;
+
message CastMessage {
// Always pass a version of the protocol for future compatibility
// requirements.
@@ -11,6 +15,7 @@ message CastMessage {
CASTV2_1_0 = 0;
}
required ProtocolVersion protocol_version = 1;
+
// source and destination ids identify the origin and destination of the
// message. They are used to route messages between endpoints that share a
// device-to-device channel.
@@ -27,39 +32,57 @@ message CastMessage {
// wildcard destination_id '*' can be used.
required string source_id = 2;
required string destination_id = 3;
+
// This is the core multiplexing key. All messages are sent on a namespace
// and endpoints sharing a channel listen on one or more namespaces. The
// namespace defines the protocol and semantics of the message.
required string namespace = 4;
+
// Encoding and payload info follows.
+
// What type of data do we have in this message.
enum PayloadType {
STRING = 0;
BINARY = 1;
}
required PayloadType payload_type = 5;
+
// Depending on payload_type, exactly one of the following optional fields
// will always be set.
optional string payload_utf8 = 6;
optional bytes payload_binary = 7;
}
+
enum SignatureAlgorithm {
UNSPECIFIED = 0;
RSASSA_PKCS1v15 = 1;
RSASSA_PSS = 2;
}
+
+enum HashAlgorithm {
+ SHA1 = 0;
+ SHA256 = 1;
+}
+
// Messages for authentication protocol between a sender and a receiver.
message AuthChallenge {
optional SignatureAlgorithm signature_algorithm = 1
[default = RSASSA_PKCS1v15];
+ optional bytes sender_nonce = 2;
+ optional HashAlgorithm hash_algorithm = 3 [default = SHA1];
}
+
message AuthResponse {
required bytes signature = 1;
required bytes client_auth_certificate = 2;
repeated bytes intermediate_certificate = 3;
optional SignatureAlgorithm signature_algorithm = 4
[default = RSASSA_PKCS1v15];
+ optional bytes sender_nonce = 5;
+ optional HashAlgorithm hash_algorithm = 6 [default = SHA1];
+ optional bytes crl = 7;
}
+
message AuthError {
enum ErrorType {
INTERNAL_ERROR = 0;
@@ -68,10 +91,11 @@ message AuthError {
}
required ErrorType error_type = 1;
}
+
message DeviceAuthMessage {
// Request fields
optional AuthChallenge challenge = 1;
// Response fields
optional AuthResponse response = 2;
optional AuthError error = 3;
-}
\ No newline at end of file
+}
diff --git a/chromecast_protobuf/logging.proto b/chromecast_protobuf/logging.proto
index c5a901d..a199c01 100644
--- a/chromecast_protobuf/logging.proto
+++ b/chromecast_protobuf/logging.proto
@@ -1,9 +1,13 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
syntax = "proto2";
+
option optimize_for = LITE_RUNTIME;
-package extensions.core_api.cast_channel.proto;
+
+package extensions.api.cast_channel.proto;
+
enum EventType {
EVENT_TYPE_UNKNOWN = 0;
CAST_SOCKET_CREATED = 1;
@@ -38,12 +42,14 @@ enum EventType {
AUTH_CHALLENGE_REPLY_INVALID = 32;
PING_WRITE_ERROR = 33; // Logged with RV.
}
+
enum ChannelAuth {
// SSL over TCP.
SSL = 1;
// SSL over TCP with challenge and receiver signature verification.
SSL_VERIFIED = 2;
}
+
enum ReadyState {
READY_STATE_NONE = 1;
READY_STATE_CONNECTING = 2;
@@ -51,8 +57,9 @@ enum ReadyState {
READY_STATE_CLOSING = 4;
READY_STATE_CLOSED = 5;
}
+
enum ConnectionState {
- CONN_STATE_NONE = 1;
+ CONN_STATE_UNKNOWN = 1;
CONN_STATE_TCP_CONNECT = 2;
CONN_STATE_TCP_CONNECT_COMPLETE = 3;
CONN_STATE_SSL_CONNECT = 4;
@@ -60,21 +67,35 @@ enum ConnectionState {
CONN_STATE_AUTH_CHALLENGE_SEND = 6;
CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE = 7;
CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE = 8;
+ CONN_STATE_START_CONNECT = 9;
+
+ // Terminal states follow.
+ CONN_STATE_FINISHED = 100;
+ CONN_STATE_ERROR = 101;
+ CONN_STATE_TIMEOUT = 102;
}
+
enum ReadState {
- READ_STATE_NONE = 1;
+ READ_STATE_UNKNOWN = 1;
READ_STATE_READ = 2;
READ_STATE_READ_COMPLETE = 3;
READ_STATE_DO_CALLBACK = 4;
- READ_STATE_ERROR = 5;
+ READ_STATE_HANDLE_ERROR = 5;
+ READ_STATE_ERROR = 100; // Terminal state.
}
+
enum WriteState {
- WRITE_STATE_NONE = 1;
+ WRITE_STATE_UNKNOWN = 1;
WRITE_STATE_WRITE = 2;
WRITE_STATE_WRITE_COMPLETE = 3;
WRITE_STATE_DO_CALLBACK = 4;
- WRITE_STATE_ERROR = 5;
+ WRITE_STATE_HANDLE_ERROR = 5;
+
+ // Terminal states follow.
+ WRITE_STATE_ERROR = 100;
+ WRITE_STATE_IDLE = 101;
}
+
enum ErrorState {
CHANNEL_ERROR_NONE = 1;
CHANNEL_ERROR_CHANNEL_NOT_OPEN = 2;
@@ -87,6 +108,7 @@ enum ErrorState {
CHANNEL_ERROR_CONNECT_TIMEOUT = 9;
CHANNEL_ERROR_UNKNOWN = 10;
}
+
enum ChallengeReplyErrorType {
CHALLENGE_REPLY_ERROR_NONE = 1;
CHALLENGE_REPLY_ERROR_PEER_CERT_EMPTY = 2;
@@ -100,22 +122,35 @@ enum ChallengeReplyErrorType {
CHALLENGE_REPLY_ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA = 10;
CHALLENGE_REPLY_ERROR_CANNOT_EXTRACT_PUBLIC_KEY = 11;
CHALLENGE_REPLY_ERROR_SIGNED_BLOBS_MISMATCH = 12;
+ CHALLENGE_REPLY_ERROR_TLS_CERT_VALIDITY_PERIOD_TOO_LONG = 13;
+ CHALLENGE_REPLY_ERROR_TLS_CERT_VALID_START_DATE_IN_FUTURE = 14;
+ CHALLENGE_REPLY_ERROR_TLS_CERT_EXPIRED = 15;
+ CHALLENGE_REPLY_ERROR_CRL_INVALID = 16;
+ CHALLENGE_REPLY_ERROR_CERT_REVOKED = 17;
}
+
message SocketEvent {
// Required
optional EventType type = 1;
optional int64 timestamp_micros = 2;
+
optional string details = 3;
+
optional int32 net_return_value = 4;
+
optional string message_namespace = 5;
+
optional ReadyState ready_state = 6;
optional ConnectionState connection_state = 7;
optional ReadState read_state = 8;
optional WriteState write_state = 9;
optional ErrorState error_state = 10;
+
optional ChallengeReplyErrorType challenge_reply_error_type = 11;
+ // No longer used.
optional int32 nss_error_code = 12;
}
+
message AggregatedSocketEvent {
optional int32 id = 1;
optional int32 endpoint_id = 2;
@@ -124,11 +159,14 @@ message AggregatedSocketEvent {
optional int64 bytes_read = 5;
optional int64 bytes_written = 6;
}
+
message Log {
// Each AggregatedSocketEvent represents events recorded for a socket.
repeated AggregatedSocketEvent aggregated_socket_event = 1;
+
// Number of socket log entries evicted by the logger due to size constraints.
optional int32 num_evicted_aggregated_socket_events = 2;
+
// Number of event log entries evicted by the logger due to size constraints.
optional int32 num_evicted_socket_events = 3;
-}
\ No newline at end of file
+}
diff --git a/example.py b/examples/blocking.py
similarity index 86%
rename from example.py
rename to examples/blocking.py
index 173139b..043e69e 100644
--- a/example.py
+++ b/examples/blocking.py
@@ -1,5 +1,8 @@
"""
Example that shows how the new Python 2 socket client can be used.
+
+Functions called in this example are blocking which means that
+the function doesn't return as long as no result was received.
"""
from __future__ import print_function
@@ -13,7 +16,12 @@ import pychromecast.controllers.youtube as youtube
if '--show-debug' in sys.argv:
logging.basicConfig(level=logging.DEBUG)
-cast = pychromecast.get_chromecast()
+casts = pychromecast.get_chromecasts()
+if len(casts) == 0:
+ print("No Devices Found")
+ exit()
+cast = casts[0]
+
yt = youtube.YouTubeController()
cast.register_handler(yt)
diff --git a/examples/non_blocking.py b/examples/non_blocking.py
new file mode 100644
index 0000000..17df777
--- /dev/null
+++ b/examples/non_blocking.py
@@ -0,0 +1,82 @@
+"""
+Example that shows how the new Python 2 socket client can be used.
+
+All functions (except get_chromecast()) are non-blocking and
+return immediately without waiting for the result. You can use
+that functionality to include pychromecast into your main loop.
+"""
+
+from __future__ import print_function
+import time
+import select
+import sys
+import logging
+
+import pychromecast
+
+"""
+Check for cast.socket_client.get_socket() and
+handle it with cast.socket_client.run_once()
+"""
+def your_main_loop():
+ t = 1
+ cast = None
+ def callback(chromecast):
+ nonlocal cast
+ cast = chromecast
+ stop_discovery()
+
+ stop_discovery = pychromecast.get_chromecasts(blocking=False, callback=callback)
+
+ while True:
+ if cast:
+ polltime = 0.1
+ can_read, _, _ = select.select([cast.socket_client.get_socket()], [], [], polltime)
+ if can_read:
+ #received something on the socket, handle it with run_once()
+ cast.socket_client.run_once()
+ do_actions(cast, t)
+ t += 1
+ if(t > 50):
+ break
+ else:
+ print("=> Waiting for cast discovery...")
+ time.sleep(1)
+
+"""
+Your code which is called by main loop
+"""
+def do_actions(cast, t):
+ if t == 5:
+ print()
+ print("=> Sending non-blocking play_media command")
+ cast.play_media(
+ ("http://commondatastorage.googleapis.com/gtv-videos-bucket/"
+ "sample/BigBuckBunny.mp4"), "video/mp4")
+ elif t == 30:
+ print()
+ print("=> Sending non-blocking pause command")
+ cast.media_controller.pause()
+ elif t == 35:
+ print()
+ print("=> Sending non-blocking play command")
+ cast.media_controller.play()
+ elif t == 40:
+ print()
+ print("=> Sending non-blocking stop command")
+ cast.media_controller.stop()
+ elif t == 45:
+ print()
+ print("=> Sending non-blocking quit_app command")
+ cast.quit_app()
+ elif t % 4 == 0:
+ print()
+ print("Media status", cast.media_controller.status)
+
+if '--show-debug' in sys.argv:
+ logging.basicConfig(level=logging.DEBUG)
+else:
+ logging.basicConfig(level=logging.INFO)
+
+your_main_loop()
+
diff --git a/pychromecast/__init__.py b/pychromecast/__init__.py
index 083401d..f2dfed3 100644
--- a/pychromecast/__init__.py
+++ b/pychromecast/__init__.py
@@ -12,15 +12,13 @@ import threading
from .config import * # noqa
from .error import * # noqa
from . import socket_client
-from .discovery import discover_chromecasts
+from .discovery import discover_chromecasts, start_discovery, stop_discovery
from .dial import get_device_status, reboot, DeviceStatus, CAST_TYPES, \
CAST_TYPE_CHROMECAST
from .controllers.media import STREAM_TYPE_BUFFERED # noqa
__all__ = (
- '__version__', '__version_info__',
- 'get_chromecasts', 'get_chromecasts_as_dict', 'get_chromecast',
- 'Chromecast'
+ '__version__', '__version_info__', 'get_chromecasts', 'Chromecast',
)
__version_info__ = ('0', '7', '6')
__version__ = '.'.join(__version_info__)
@@ -31,50 +29,39 @@ IGNORE_CEC = []
NON_UNICODE_REPR = sys.version_info < (3, )
-def _get_all_chromecasts(tries=None, retry_wait=None, timeout=None):
+def _get_chromecast_from_host(host, tries=None, retry_wait=None, timeout=None,
+ blocking=True):
+ """Creates a Chromecast object from a zeroconf host."""
+ # Build device status from the mDNS info, this information is
+ # the primary source and the remaining will be fetched
+ # later on.
+ ip_address, port, uuid, model_name, friendly_name = host
+ cast_type = CAST_TYPES.get(model_name.lower(),
+ CAST_TYPE_CHROMECAST)
+ device = DeviceStatus(
+ friendly_name=friendly_name, model_name=model_name,
+ manufacturer=None, api_version=None,
+ uuid=uuid, cast_type=cast_type,
+ )
+ return Chromecast(host=ip_address, port=port, device=device, tries=tries,
+ timeout=timeout, retry_wait=retry_wait,
+ blocking=blocking)
+
+
+# pylint: disable=too-many-locals
+def get_chromecasts(tries=None, retry_wait=None, timeout=None,
+ blocking=True, callback=None):
"""
- Returns a list of all chromecasts on the network as PyChromecast
- objects.
- """
- hosts = discover_chromecasts()
- cc_list = []
- for ip_address, port, uuid, model_name, friendly_name in hosts:
- try:
- # Build device status from the mDNS info, this information is
- # the primary source and the remaining will be fetched
- # later on.
- cast_type = CAST_TYPES.get(model_name.lower(),
- CAST_TYPE_CHROMECAST)
- device = DeviceStatus(
- friendly_name=friendly_name, model_name=model_name,
- manufacturer=None, api_version=None,
- uuid=uuid, cast_type=cast_type,
- )
- cc_list.append(Chromecast(host=ip_address, port=port,
- device=device,
- tries=tries, timeout=timeout,
- retry_wait=retry_wait))
- except ChromecastConnectionError: # noqa
- pass
- return cc_list
+ Searches the network for chromecast devices.
-
-def get_chromecasts(tries=None, retry_wait=None, timeout=None, **filters):
- """
- Searches the network and returns a list of Chromecast objects.
- Filter is a list of options to filter the chromecasts by.
+ If blocking = True, returns a list of discovered chromecast devices.
+ If blocking = False, triggers a callback for each discovered chromecast,
+ and returns a function which can be executed to stop
+ discovery.
ex: get_chromecasts(friendly_name="Living Room")
- May return an empty list if no chromecasts were found matching
- the filter criteria
-
- Filters include DeviceStatus items:
- friendly_name, model_name, manufacturer, api_version
- Or AppStatus items:
- app_id, description, state, service_url, service_protocols (list)
- Or ip address:
- ip
+ May return an empty list if no chromecasts were found.
Tries is specified if you want to limit the number of times the
underlying socket associated with your Chromecast objects will
@@ -83,102 +70,39 @@ def get_chromecasts(tries=None, retry_wait=None, timeout=None, **filters):
can be defined by passing the retry_wait parameter, the default is
to wait 5 seconds.
"""
- logger = logging.getLogger(__name__)
-
- cc_list = set(_get_all_chromecasts(tries, retry_wait, timeout))
- excluded_cc = set()
-
- if not filters:
- return list(cc_list)
-
- if 'ip' in filters:
- for chromecast in cc_list:
- if chromecast.host != filters['ip']:
- excluded_cc.add(chromecast)
- filters.pop('ip')
-
- for key, val in filters.items():
- for chromecast in cc_list:
- for tup in [chromecast.device, chromecast.status]:
- if hasattr(tup, key) and val != getattr(tup, key):
- excluded_cc.add(chromecast)
-
- filtered_cc = cc_list - excluded_cc
-
- for cast in excluded_cc:
- logger.debug("Stopping excluded chromecast %s", cast)
- cast.socket_client.stop.set()
-
- return list(filtered_cc)
-
-
-def get_chromecasts_as_dict(tries=None, retry_wait=None, timeout=None,
- **filters):
- """
- Returns a dictionary of chromecasts with the friendly name as
- the key. The value is the pychromecast object itself.
-
- Tries is specified if you want to limit the number of times the
- underlying socket associated with your Chromecast objects will
- retry connecting if connection is lost or it fails to connect
- in the first place. The number of seconds spent between each retry
- can be defined by passing the retry_wait parameter, the default is
- to wait 5 seconds.
- """
- return {cc.device.friendly_name: cc
- for cc in get_chromecasts(tries=tries, retry_wait=retry_wait,
- timeout=timeout,
- **filters)}
-
-
-def get_chromecast(strict=False, tries=None, retry_wait=None, timeout=None,
- **filters):
- """
- Same as get_chromecasts but only if filter matches exactly one
- ChromeCast.
-
- Returns a Chromecast matching exactly the fitler specified.
-
- If strict, return one and only one chromecast
-
- Tries is specified if you want to limit the number of times the
- underlying socket associated with your Chromecast objects will
- retry connecting if connection is lost or it fails to connect
- in the first place. The number of seconds spent between each retry
- can be defined by passing the retry_wait parameter, the default is
- to wait 5 seconds.
-
- :type retry_wait: float or None
- """
-
- # If we have filters or are operating in strict mode we have to scan
- # for all Chromecasts to ensure there is only 1 matching chromecast.
- # If no filters given and not strict just use the first dicsovered one.
- if filters or strict:
- results = get_chromecasts(tries=tries, retry_wait=retry_wait,
- timeout=timeout,
- **filters)
+ if blocking:
+ # Thread blocking chromecast discovery
+ hosts = discover_chromecasts()
+ cc_list = []
+ for host in hosts:
+ try:
+ cc_list.append(_get_chromecast_from_host(
+ host, tries=tries, retry_wait=retry_wait, timeout=timeout,
+ blocking=blocking))
+ except ChromecastConnectionError: # noqa
+ pass
+ return cc_list
else:
- results = _get_all_chromecasts(tries, retry_wait)
+ # Callback based chromecast discovery
+ if not callable(callback):
+ raise ValueError(
+ "Nonblocking discovery requires a callback function.")
- if len(results) > 1:
- if strict:
- raise MultipleChromecastsFoundError( # noqa
- 'More than one Chromecast was found specifying '
- 'the filter criteria: {}'.format(filters))
- else:
- return results[0]
+ def internal_callback(name):
+ """Called when zeroconf has discovered a new chromecast."""
+ try:
+ callback(_get_chromecast_from_host(
+ listener.services[name], tries=tries,
+ retry_wait=retry_wait, timeout=timeout, blocking=blocking))
+ except ChromecastConnectionError: # noqa
+ pass
- elif not results:
- if strict:
- raise NoChromecastFoundError( # noqa
- 'No Chromecasts matching filter critera were found:'
- ' {}'.format(filters))
- else:
- return None
+ def internal_stop():
+ """Stops discovery of new chromecasts."""
+ stop_discovery(browser)
- else:
- return results[0]
+ listener, browser = start_discovery(internal_callback)
+ return internal_stop
# pylint: disable=too-many-instance-attributes
@@ -204,6 +128,7 @@ class Chromecast(object):
tries = kwargs.pop('tries', None)
timeout = kwargs.pop('timeout', None)
retry_wait = kwargs.pop('retry_wait', None)
+ blocking = kwargs.pop('blocking', True)
self.logger = logging.getLogger(__name__)
@@ -248,7 +173,8 @@ class Chromecast(object):
self.socket_client = socket_client.SocketClient(
host, port=port, cast_type=self.device.cast_type,
- tries=tries, timeout=timeout, retry_wait=retry_wait)
+ tries=tries, timeout=timeout, retry_wait=retry_wait,
+ blocking=blocking)
receiver_controller = self.socket_client.receiver_controller
receiver_controller.register_status_listener(self)
@@ -265,7 +191,8 @@ class Chromecast(object):
self.register_connection_listener = \
self.socket_client.register_connection_listener
- self.socket_client.start()
+ if blocking:
+ self.socket_client.start()
@property
def ignore_cec(self):
@@ -349,20 +276,24 @@ class Chromecast(object):
""" Reboots the Chromecast. """
reboot(self.host)
- def volume_up(self):
- """ Increment volume by 0.1 unless it is already maxed.
+ def volume_up(self, delta=0.1):
+ """ Increment volume by 0.1 (or delta) unless it is already maxed.
Returns the new volume.
"""
- volume = round(self.status.volume_level, 1)
- return self.set_volume(volume + 0.1)
+ if delta <= 0:
+ raise ValueError(
+ "volume delta must be greater than zero, not {}".format(delta))
+ return self.set_volume(self.status.volume_level + delta)
- def volume_down(self):
- """ Decrement the volume by 0.1 unless it is already 0.
+ def volume_down(self, delta=0.1):
+ """ Decrement the volume by 0.1 (or delta) unless it is already 0.
Returns the new volume.
"""
- volume = round(self.status.volume_level, 1)
- return self.set_volume(volume - 0.1)
+ if delta <= 0:
+ raise ValueError(
+ "volume delta must be greater than zero, not {}".format(delta))
+ return self.set_volume(self.status.volume_level - delta)
def wait(self, timeout=None):
"""
diff --git a/pychromecast/authority_keys_pb2.py b/pychromecast/authority_keys_pb2.py
index 82684c1..226c3a7 100644
--- a/pychromecast/authority_keys_pb2.py
+++ b/pychromecast/authority_keys_pb2.py
@@ -17,9 +17,9 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='authority_keys.proto',
- package='extensions.core_api.cast_channel.proto',
+ package='extensions.api.cast_channel.proto',
syntax='proto2',
- serialized_pb=_b('\n\x14\x61uthority_keys.proto\x12&extensions.core_api.cast_channel.proto\"\x88\x01\n\rAuthorityKeys\x12G\n\x04keys\x18\x01 \x03(\x0b\x32\x39.extensions.core_api.cast_channel.proto.AuthorityKeys.Key\x1a.\n\x03Key\x12\x13\n\x0b\x66ingerprint\x18\x01 \x02(\x0c\x12\x12\n\npublic_key\x18\x02 \x02(\x0c\x42\x02H\x03')
+ serialized_pb=_b('\n\x14\x61uthority_keys.proto\x12!extensions.api.cast_channel.proto\"\x83\x01\n\rAuthorityKeys\x12\x42\n\x04keys\x18\x01 \x03(\x0b\x32\x34.extensions.api.cast_channel.proto.AuthorityKeys.Key\x1a.\n\x03Key\x12\x13\n\x0b\x66ingerprint\x18\x01 \x02(\x0c\x12\x12\n\npublic_key\x18\x02 \x02(\x0c\x42\x02H\x03')
)
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
@@ -28,20 +28,20 @@ _sym_db.RegisterFileDescriptor(DESCRIPTOR)
_AUTHORITYKEYS_KEY = _descriptor.Descriptor(
name='Key',
- full_name='extensions.core_api.cast_channel.proto.AuthorityKeys.Key',
+ full_name='extensions.api.cast_channel.proto.AuthorityKeys.Key',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
- name='fingerprint', full_name='extensions.core_api.cast_channel.proto.AuthorityKeys.Key.fingerprint', index=0,
+ name='fingerprint', full_name='extensions.api.cast_channel.proto.AuthorityKeys.Key.fingerprint', index=0,
number=1, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
- name='public_key', full_name='extensions.core_api.cast_channel.proto.AuthorityKeys.Key.public_key', index=1,
+ name='public_key', full_name='extensions.api.cast_channel.proto.AuthorityKeys.Key.public_key', index=1,
number=2, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
@@ -59,19 +59,19 @@ _AUTHORITYKEYS_KEY = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=155,
- serialized_end=201,
+ serialized_start=145,
+ serialized_end=191,
)
_AUTHORITYKEYS = _descriptor.Descriptor(
name='AuthorityKeys',
- full_name='extensions.core_api.cast_channel.proto.AuthorityKeys',
+ full_name='extensions.api.cast_channel.proto.AuthorityKeys',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
- name='keys', full_name='extensions.core_api.cast_channel.proto.AuthorityKeys.keys', index=0,
+ name='keys', full_name='extensions.api.cast_channel.proto.AuthorityKeys.keys', 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,
@@ -89,8 +89,8 @@ _AUTHORITYKEYS = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=65,
- serialized_end=201,
+ serialized_start=60,
+ serialized_end=191,
)
_AUTHORITYKEYS_KEY.containing_type = _AUTHORITYKEYS
@@ -102,12 +102,12 @@ AuthorityKeys = _reflection.GeneratedProtocolMessageType('AuthorityKeys', (_mess
Key = _reflection.GeneratedProtocolMessageType('Key', (_message.Message,), dict(
DESCRIPTOR = _AUTHORITYKEYS_KEY,
__module__ = 'authority_keys_pb2'
- # @@protoc_insertion_point(class_scope:extensions.core_api.cast_channel.proto.AuthorityKeys.Key)
+ # @@protoc_insertion_point(class_scope:extensions.api.cast_channel.proto.AuthorityKeys.Key)
))
,
DESCRIPTOR = _AUTHORITYKEYS,
__module__ = 'authority_keys_pb2'
- # @@protoc_insertion_point(class_scope:extensions.core_api.cast_channel.proto.AuthorityKeys)
+ # @@protoc_insertion_point(class_scope:extensions.api.cast_channel.proto.AuthorityKeys)
))
_sym_db.RegisterMessage(AuthorityKeys)
_sym_db.RegisterMessage(AuthorityKeys.Key)
diff --git a/pychromecast/cast_channel_pb2.py b/pychromecast/cast_channel_pb2.py
index 1893718..eb3317f 100644
--- a/pychromecast/cast_channel_pb2.py
+++ b/pychromecast/cast_channel_pb2.py
@@ -18,15 +18,15 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='cast_channel.proto',
- package='extensions.core_api.cast_channel',
+ package='extensions.api.cast_channel',
syntax='proto2',
- serialized_pb=_b('\n\x12\x63\x61st_channel.proto\x12 extensions.core_api.cast_channel\"\xed\x02\n\x0b\x43\x61stMessage\x12W\n\x10protocol_version\x18\x01 \x02(\x0e\x32=.extensions.core_api.cast_channel.CastMessage.ProtocolVersion\x12\x11\n\tsource_id\x18\x02 \x02(\t\x12\x16\n\x0e\x64\x65stination_id\x18\x03 \x02(\t\x12\x11\n\tnamespace\x18\x04 \x02(\t\x12O\n\x0cpayload_type\x18\x05 \x02(\x0e\x32\x39.extensions.core_api.cast_channel.CastMessage.PayloadType\x12\x14\n\x0cpayload_utf8\x18\ [...]
+ serialized_pb=_b('\n\x12\x63\x61st_channel.proto\x12\x1b\x65xtensions.api.cast_channel\"\xe3\x02\n\x0b\x43\x61stMessage\x12R\n\x10protocol_version\x18\x01 \x02(\x0e\x32\x38.extensions.api.cast_channel.CastMessage.ProtocolVersion\x12\x11\n\tsource_id\x18\x02 \x02(\t\x12\x16\n\x0e\x64\x65stination_id\x18\x03 \x02(\t\x12\x11\n\tnamespace\x18\x04 \x02(\t\x12J\n\x0cpayload_type\x18\x05 \x02(\x0e\x32\x34.extensions.api.cast_channel.CastMessage.PayloadType\x12\x14\n\x0cpayload_utf8\x18\x06 \x [...]
)
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
_SIGNATUREALGORITHM = _descriptor.EnumDescriptor(
name='SignatureAlgorithm',
- full_name='extensions.core_api.cast_channel.SignatureAlgorithm',
+ full_name='extensions.api.cast_channel.SignatureAlgorithm',
filename=None,
file=DESCRIPTOR,
values=[
@@ -45,20 +45,45 @@ _SIGNATUREALGORITHM = _descriptor.EnumDescriptor(
],
containing_type=None,
options=None,
- serialized_start=1131,
- serialized_end=1205,
+ serialized_start=1292,
+ serialized_end=1366,
)
_sym_db.RegisterEnumDescriptor(_SIGNATUREALGORITHM)
SignatureAlgorithm = enum_type_wrapper.EnumTypeWrapper(_SIGNATUREALGORITHM)
+_HASHALGORITHM = _descriptor.EnumDescriptor(
+ name='HashAlgorithm',
+ full_name='extensions.api.cast_channel.HashAlgorithm',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ _descriptor.EnumValueDescriptor(
+ name='SHA1', index=0, number=0,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='SHA256', index=1, number=1,
+ options=None,
+ type=None),
+ ],
+ containing_type=None,
+ options=None,
+ serialized_start=1368,
+ serialized_end=1405,
+)
+_sym_db.RegisterEnumDescriptor(_HASHALGORITHM)
+
+HashAlgorithm = enum_type_wrapper.EnumTypeWrapper(_HASHALGORITHM)
UNSPECIFIED = 0
RSASSA_PKCS1v15 = 1
RSASSA_PSS = 2
+SHA1 = 0
+SHA256 = 1
_CASTMESSAGE_PROTOCOLVERSION = _descriptor.EnumDescriptor(
name='ProtocolVersion',
- full_name='extensions.core_api.cast_channel.CastMessage.ProtocolVersion',
+ full_name='extensions.api.cast_channel.CastMessage.ProtocolVersion',
filename=None,
file=DESCRIPTOR,
values=[
@@ -69,14 +94,14 @@ _CASTMESSAGE_PROTOCOLVERSION = _descriptor.EnumDescriptor(
],
containing_type=None,
options=None,
- serialized_start=350,
- serialized_end=383,
+ serialized_start=335,
+ serialized_end=368,
)
_sym_db.RegisterEnumDescriptor(_CASTMESSAGE_PROTOCOLVERSION)
_CASTMESSAGE_PAYLOADTYPE = _descriptor.EnumDescriptor(
name='PayloadType',
- full_name='extensions.core_api.cast_channel.CastMessage.PayloadType',
+ full_name='extensions.api.cast_channel.CastMessage.PayloadType',
filename=None,
file=DESCRIPTOR,
values=[
@@ -91,14 +116,14 @@ _CASTMESSAGE_PAYLOADTYPE = _descriptor.EnumDescriptor(
],
containing_type=None,
options=None,
- serialized_start=385,
- serialized_end=422,
+ serialized_start=370,
+ serialized_end=407,
)
_sym_db.RegisterEnumDescriptor(_CASTMESSAGE_PAYLOADTYPE)
_AUTHERROR_ERRORTYPE = _descriptor.EnumDescriptor(
name='ErrorType',
- full_name='extensions.core_api.cast_channel.AuthError.ErrorType',
+ full_name='extensions.api.cast_channel.AuthError.ErrorType',
filename=None,
file=DESCRIPTOR,
values=[
@@ -117,63 +142,63 @@ _AUTHERROR_ERRORTYPE = _descriptor.EnumDescriptor(
],
containing_type=None,
options=None,
- serialized_start=833,
- serialized_end=913,
+ serialized_start=1009,
+ serialized_end=1089,
)
_sym_db.RegisterEnumDescriptor(_AUTHERROR_ERRORTYPE)
_CASTMESSAGE = _descriptor.Descriptor(
name='CastMessage',
- full_name='extensions.core_api.cast_channel.CastMessage',
+ full_name='extensions.api.cast_channel.CastMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
- name='protocol_version', full_name='extensions.core_api.cast_channel.CastMessage.protocol_version', index=0,
+ name='protocol_version', full_name='extensions.api.cast_channel.CastMessage.protocol_version', index=0,
number=1, type=14, cpp_type=8, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
- name='source_id', full_name='extensions.core_api.cast_channel.CastMessage.source_id', index=1,
+ name='source_id', full_name='extensions.api.cast_channel.CastMessage.source_id', 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,
options=None),
_descriptor.FieldDescriptor(
- name='destination_id', full_name='extensions.core_api.cast_channel.CastMessage.destination_id', index=2,
+ name='destination_id', full_name='extensions.api.cast_channel.CastMessage.destination_id', index=2,
number=3, 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,
options=None),
_descriptor.FieldDescriptor(
- name='namespace', full_name='extensions.core_api.cast_channel.CastMessage.namespace', index=3,
+ name='namespace', full_name='extensions.api.cast_channel.CastMessage.namespace', index=3,
number=4, 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,
options=None),
_descriptor.FieldDescriptor(
- name='payload_type', full_name='extensions.core_api.cast_channel.CastMessage.payload_type', index=4,
+ name='payload_type', full_name='extensions.api.cast_channel.CastMessage.payload_type', index=4,
number=5, type=14, cpp_type=8, label=2,
... 1486 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pychromecast.git
More information about the Python-modules-commits
mailing list