PyChromecast 14.0.1__tar.gz → 14.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/PKG-INFO +7 -1
  2. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/PyChromecast.egg-info/PKG-INFO +7 -1
  3. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/README.rst +6 -0
  4. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/const.py +1 -0
  5. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/plex.py +2 -0
  6. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/youtube.py +1 -0
  7. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/socket_client.py +36 -37
  8. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pyproject.toml +1 -1
  9. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/requirements.txt +1 -1
  10. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/LICENSE +0 -0
  11. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/MANIFEST.in +0 -0
  12. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/PyChromecast.egg-info/SOURCES.txt +0 -0
  13. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/PyChromecast.egg-info/dependency_links.txt +0 -0
  14. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/PyChromecast.egg-info/not-zip-safe +0 -0
  15. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/PyChromecast.egg-info/requires.txt +0 -0
  16. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/PyChromecast.egg-info/top_level.txt +0 -0
  17. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/__init__.py +0 -0
  18. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/config.py +0 -0
  19. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/__init__.py +0 -0
  20. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/bbciplayer.py +0 -0
  21. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/bbcsounds.py +0 -0
  22. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/bubbleupnp.py +0 -0
  23. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/dashcast.py +0 -0
  24. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/homeassistant.py +0 -0
  25. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/homeassistant_media.py +0 -0
  26. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/media.py +0 -0
  27. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/multizone.py +0 -0
  28. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/nrkradio.py +0 -0
  29. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/nrktv.py +0 -0
  30. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/receiver.py +0 -0
  31. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/shaka.py +0 -0
  32. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/supla.py +0 -0
  33. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/controllers/yleareena.py +0 -0
  34. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/dial.py +0 -0
  35. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/discovery.py +0 -0
  36. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/error.py +0 -0
  37. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/generated/authority_keys_pb2.py +0 -0
  38. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/generated/authority_keys_pb2.pyi +0 -0
  39. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/generated/cast_channel_pb2.py +0 -0
  40. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/generated/cast_channel_pb2.pyi +0 -0
  41. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/generated/logging_pb2.py +0 -0
  42. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/generated/logging_pb2.pyi +0 -0
  43. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/generated/readme.txt +0 -0
  44. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/models.py +0 -0
  45. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/quick_play.py +0 -0
  46. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/pychromecast/response_handler.py +0 -0
  47. {PyChromecast-14.0.1 → PyChromecast-14.0.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyChromecast
3
- Version: 14.0.1
3
+ Version: 14.0.2
4
4
  Summary: Python module to talk to Google Chromecast.
5
5
  Author-email: Paulus Schoutsen <paulus@paulusschoutsen.nl>
6
6
  Project-URL: Homepage, https://github.com/home-assistant-libs/pychromecast
@@ -192,3 +192,9 @@ work. Without him it would not have been possible!
192
192
 
193
193
  .. _Linux style wildcard: http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm
194
194
  .. _Fred Clift: https://github.com/minektur
195
+
196
+ |ohf-logo|
197
+
198
+ .. |ohf-logo| image:: https://www.openhomefoundation.org/badges/pychromecast.png
199
+ :alt: PyChromecast - A library from the Open Home Foundation
200
+ :target: https://www.openhomefoundation.org/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyChromecast
3
- Version: 14.0.1
3
+ Version: 14.0.2
4
4
  Summary: Python module to talk to Google Chromecast.
5
5
  Author-email: Paulus Schoutsen <paulus@paulusschoutsen.nl>
6
6
  Project-URL: Homepage, https://github.com/home-assistant-libs/pychromecast
@@ -192,3 +192,9 @@ work. Without him it would not have been possible!
192
192
 
193
193
  .. _Linux style wildcard: http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm
194
194
  .. _Fred Clift: https://github.com/minektur
195
+
196
+ |ohf-logo|
197
+
198
+ .. |ohf-logo| image:: https://www.openhomefoundation.org/badges/pychromecast.png
199
+ :alt: PyChromecast - A library from the Open Home Foundation
200
+ :target: https://www.openhomefoundation.org/
@@ -175,3 +175,9 @@ work. Without him it would not have been possible!
175
175
 
176
176
  .. _Linux style wildcard: http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm
177
177
  .. _Fred Clift: https://github.com/minektur
178
+
179
+ |ohf-logo|
180
+
181
+ .. |ohf-logo| image:: https://www.openhomefoundation.org/badges/pychromecast.png
182
+ :alt: PyChromecast - A library from the Open Home Foundation
183
+ :target: https://www.openhomefoundation.org/
@@ -43,6 +43,7 @@ CAST_TYPES = {
43
43
  "nest audio": (CAST_TYPE_AUDIO, MF_GOOGLE),
44
44
  "nest wifi point": (CAST_TYPE_AUDIO, MF_GOOGLE),
45
45
  "bravia 4k vh2": (CAST_TYPE_CHROMECAST, MF_SONY),
46
+ "bravia 4k vh21": (CAST_TYPE_CHROMECAST, MF_SONY),
46
47
  "C4A": (CAST_TYPE_AUDIO, MF_SONY),
47
48
  "JBL Link 10": (CAST_TYPE_AUDIO, MF_JBL),
48
49
  "JBL Link 20": (CAST_TYPE_AUDIO, MF_JBL),
@@ -108,6 +108,8 @@ def media_to_chromecast_command( # pylint: disable=invalid-name, too-many-local
108
108
  dict: Returs a dict formatted correctly to start playback on a Chromecast.
109
109
  """
110
110
 
111
+ machineIdentifier = None
112
+ token = None
111
113
  if media is not None:
112
114
  # Lets set some params for the user if they use plexapi.
113
115
  server: PlexServer = (
@@ -84,6 +84,7 @@ class YouTubeController(QuickPlayController):
84
84
  super().__init__(YOUTUBE_NAMESPACE, APP_YOUTUBE)
85
85
  self.status_update_event = threading.Event()
86
86
  self._timeout = timeout
87
+ self._session = None
87
88
 
88
89
  def start_session_if_none(self) -> None:
89
90
  """
@@ -10,31 +10,31 @@ Without him this would not have been possible.
10
10
  from __future__ import annotations
11
11
 
12
12
  import abc
13
- from dataclasses import dataclass
14
13
  import errno
15
14
  import json
16
15
  import logging
17
- import select
16
+ import selectors
18
17
  import socket
19
18
  import ssl
20
19
  import threading
21
20
  import time
22
21
  from collections import defaultdict
22
+ from dataclasses import dataclass
23
23
  from struct import pack, unpack
24
24
 
25
25
  import zeroconf
26
26
 
27
- from .controllers import CallbackType, BaseController
27
+ from .const import MESSAGE_TYPE, REQUEST_ID, SESSION_ID
28
+ from .controllers import BaseController, CallbackType
28
29
  from .controllers.media import MediaController
29
30
  from .controllers.receiver import CastStatus, CastStatusListener, ReceiverController
30
- from .const import MESSAGE_TYPE, REQUEST_ID, SESSION_ID
31
31
  from .dial import get_host_from_service
32
32
  from .error import (
33
33
  ChromecastConnectionError,
34
34
  ControllerNotRegistered,
35
- UnsupportedNamespace,
36
35
  NotConnected,
37
36
  PyChromecastStopped,
37
+ UnsupportedNamespace,
38
38
  )
39
39
 
40
40
  # pylint: disable-next=no-name-in-module
@@ -64,13 +64,9 @@ CONNECTION_STATUS_FAILED = "FAILED"
64
64
  CONNECTION_STATUS_FAILED_RESOLVE = "FAILED_RESOLVE"
65
65
  # The socket connection was lost and needs to be retried
66
66
  CONNECTION_STATUS_LOST = "LOST"
67
- # Check for select poll method
68
- SELECT_HAS_POLL = hasattr(select, "poll")
69
67
 
70
68
  HB_PING_TIME = 10
71
69
  HB_PONG_TIME = 10
72
- POLL_TIME_BLOCKING = 5.0
73
- POLL_TIME_NON_BLOCKING = 0.01
74
70
  TIMEOUT_TIME = 30.0
75
71
  RETRY_TIME = 5.0
76
72
 
@@ -215,6 +211,11 @@ class SocketClient(threading.Thread, CastStatusListener):
215
211
  self.connecting = True
216
212
  self.first_connection = True
217
213
  self.socket: socket.socket | ssl.SSLSocket | None = None
214
+ self.selector = selectors.DefaultSelector()
215
+ self.wakeup_selector_key = self.selector.register(
216
+ self.socketpair[0], selectors.EVENT_READ
217
+ )
218
+ self.remote_selector_key: selectors.SelectorKey | None = None
218
219
 
219
220
  # dict mapping namespace on Controller objects
220
221
  self._handlers: dict[str, set[BaseController]] = defaultdict(set)
@@ -238,8 +239,10 @@ class SocketClient(threading.Thread, CastStatusListener):
238
239
  tries = self.tries
239
240
 
240
241
  if self.socket is not None:
242
+ self.selector.unregister(self.socket)
241
243
  self.socket.close()
242
244
  self.socket = None
245
+ self.remote_selector_key = None
243
246
 
244
247
  # Make sure nobody is blocking.
245
248
  for callback_function in self._request_callbacks.values():
@@ -288,10 +291,15 @@ class SocketClient(threading.Thread, CastStatusListener):
288
291
  try:
289
292
  if self.socket is not None:
290
293
  # If we retry connecting, we need to clean up the socket again
291
- self.socket.close() # type: ignore[unreachable]
294
+ self.selector.unregister(self.socket) # type: ignore[unreachable]
295
+ self.socket.close()
292
296
  self.socket = None
297
+ self.remote_selector_key = None
293
298
 
294
299
  self.socket = new_socket()
300
+ self.remote_selector_key = self.selector.register(
301
+ self.socket, selectors.EVENT_READ
302
+ )
295
303
  self.socket.settimeout(self.timeout)
296
304
  self._report_connection_status(
297
305
  ConnectionStatus(
@@ -530,7 +538,7 @@ class SocketClient(threading.Thread, CastStatusListener):
530
538
  self.logger.debug("Thread started...")
531
539
  while not self.stop.is_set():
532
540
  try:
533
- if self._run_once(timeout=POLL_TIME_BLOCKING) == 1:
541
+ if self._run_once() == 1:
534
542
  break
535
543
  except Exception: # pylint: disable=broad-except
536
544
  self._force_recon = True
@@ -545,7 +553,7 @@ class SocketClient(threading.Thread, CastStatusListener):
545
553
  # Clean up
546
554
  self._cleanup()
547
555
 
548
- def _run_once(self, timeout: float = POLL_TIME_NON_BLOCKING) -> int:
556
+ def _run_once(self) -> int:
549
557
  """Receive from the socket and handle data."""
550
558
  # pylint: disable=too-many-branches, too-many-statements, too-many-return-statements
551
559
 
@@ -559,20 +567,8 @@ class SocketClient(threading.Thread, CastStatusListener):
559
567
  assert self.socket is not None
560
568
 
561
569
  # poll the socket, as well as the socketpair to allow us to be interrupted
562
- rlist = [self.socket, self.socketpair[0]]
563
570
  try:
564
- if SELECT_HAS_POLL is True:
565
- # Map file descriptors to socket objects because select.select does not support fd > 1024
566
- # https://stackoverflow.com/questions/14250751/how-to-increase-filedescriptors-range-in-python-select
567
- fd_to_socket = {rlist_item.fileno(): rlist_item for rlist_item in rlist}
568
-
569
- poll_obj = select.poll()
570
- for poll_fd in rlist:
571
- poll_obj.register(poll_fd, select.POLLIN)
572
- poll_result = poll_obj.poll(timeout * 1000) # timeout in milliseconds
573
- can_read = [fd_to_socket[fd] for fd, _status in poll_result]
574
- else:
575
- can_read, _, _ = select.select(rlist, [], [], timeout)
571
+ ready = self.selector.select()
576
572
  except (ValueError, OSError) as exc:
577
573
  self.logger.error(
578
574
  "[%s(%s):%s] Error in select call: %s",
@@ -584,9 +580,10 @@ class SocketClient(threading.Thread, CastStatusListener):
584
580
  self._force_recon = True
585
581
  return 0
586
582
 
583
+ can_read = {key for key, _ in ready}
587
584
  # read message from chromecast
588
585
  message = None
589
- if self.socket in can_read and not self._force_recon:
586
+ if self.remote_selector_key in can_read and not self._force_recon:
590
587
  try:
591
588
  message = self._read_message()
592
589
  except InterruptLoop as exc:
@@ -611,18 +608,17 @@ class SocketClient(threading.Thread, CastStatusListener):
611
608
  if self.stop.is_set():
612
609
  return 1
613
610
  raise
614
- except socket.error:
611
+ except socket.error as exc:
615
612
  self._force_recon = True
616
613
  self.logger.error(
617
- "[%s(%s):%s] Error reading from socket.",
614
+ "[%s(%s):%s] Error reading from socket: %s",
618
615
  self.fn or "",
619
616
  self.host,
620
617
  self.port,
618
+ exc,
621
619
  )
622
- else:
623
- data = _dict_from_message_payload(message)
624
620
 
625
- if self.socketpair[0] in can_read:
621
+ if self.wakeup_selector_key in can_read:
626
622
  # Clear the socket's buffer
627
623
  self.socketpair[0].recv(128)
628
624
 
@@ -635,6 +631,7 @@ class SocketClient(threading.Thread, CastStatusListener):
635
631
  return 0
636
632
 
637
633
  # See if any handlers will accept this message
634
+ data = _dict_from_message_payload(message)
638
635
  self._route_message(message, data)
639
636
 
640
637
  if REQUEST_ID in data and data[REQUEST_ID] in self._request_callbacks:
@@ -652,8 +649,8 @@ class SocketClient(threading.Thread, CastStatusListener):
652
649
  # check if connection is expired
653
650
  reset = False
654
651
  if self._force_recon:
655
- self.logger.warning(
656
- "[%s(%s):%s] Error communicating with socket, resetting connection",
652
+ self.logger.debug(
653
+ "[%s(%s):%s] Forced reconnection",
657
654
  self.fn or "",
658
655
  self.host,
659
656
  self.port,
@@ -661,7 +658,7 @@ class SocketClient(threading.Thread, CastStatusListener):
661
658
  reset = True
662
659
 
663
660
  elif self.heartbeat_controller.is_expired():
664
- self.logger.warning(
661
+ self.logger.info(
665
662
  "[%s(%s):%s] Heartbeat timeout, resetting connection",
666
663
  self.fn or "",
667
664
  self.host,
@@ -767,6 +764,7 @@ class SocketClient(threading.Thread, CastStatusListener):
767
764
 
768
765
  self.socketpair[0].close()
769
766
  self.socketpair[1].close()
767
+ self.selector.close()
770
768
 
771
769
  self.connecting = True
772
770
 
@@ -897,17 +895,18 @@ class SocketClient(threading.Thread, CastStatusListener):
897
895
  else:
898
896
  callback_function(True, None)
899
897
  self.socket.sendall(be_size + msg.SerializeToString())
900
- except socket.error:
898
+ except socket.error as exc:
901
899
  if callback_function:
902
900
  callback_function(False, None)
903
901
  if not no_add_request_id:
904
902
  self._request_callbacks.pop(request_id, None)
905
903
  self._force_recon = True
906
- self.logger.info(
907
- "[%s(%s):%s] Error writing to socket.",
904
+ self.logger.warning(
905
+ "[%s(%s):%s] Error writing to socket: %s",
908
906
  self.fn or "",
909
907
  self.host,
910
908
  self.port,
909
+ exc,
911
910
  )
912
911
  else:
913
912
  if callback_function:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "PyChromecast"
7
- version = "14.0.1"
7
+ version = "14.0.2"
8
8
  description = "Python module to talk to Google Chromecast."
9
9
  readme = "README.rst"
10
10
  authors = [
@@ -1,3 +1,3 @@
1
1
  casttube==0.2.1
2
2
  protobuf==4.25.2
3
- zeroconf==0.131.0
3
+ zeroconf==0.135.0
File without changes
File without changes
File without changes