soco-cli 0.4.73__tar.gz → 0.4.75__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 (39) hide show
  1. {soco-cli-0.4.73/soco_cli.egg-info → soco-cli-0.4.75}/PKG-INFO +1 -1
  2. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/__init__.py +1 -1
  3. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/alarms.py +12 -14
  4. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/play_local_file.py +37 -7
  5. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/speakers.py +7 -9
  6. {soco-cli-0.4.73 → soco-cli-0.4.75/soco_cli.egg-info}/PKG-INFO +1 -1
  7. {soco-cli-0.4.73 → soco-cli-0.4.75}/LICENSE +0 -0
  8. {soco-cli-0.4.73 → soco-cli-0.4.75}/MANIFEST.in +0 -0
  9. {soco-cli-0.4.73 → soco-cli-0.4.75}/PYPI_README.md +0 -0
  10. {soco-cli-0.4.73 → soco-cli-0.4.75}/README.md +0 -0
  11. {soco-cli-0.4.73 → soco-cli-0.4.75}/pyproject.toml +0 -0
  12. {soco-cli-0.4.73 → soco-cli-0.4.75}/requirements.txt +0 -0
  13. {soco-cli-0.4.73 → soco-cli-0.4.75}/setup.cfg +0 -0
  14. {soco-cli-0.4.73 → soco-cli-0.4.75}/setup.py +0 -0
  15. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/__main__.py +0 -0
  16. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/action_processor.py +0 -0
  17. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/aliases.py +0 -0
  18. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/api.py +0 -0
  19. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/check_for_update.py +0 -0
  20. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/cmd_parser.py +0 -0
  21. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/http_api.py +0 -0
  22. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/interactive.py +0 -0
  23. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/keystroke_capture.py +0 -0
  24. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/m3u_parser.py +0 -0
  25. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/match_speaker_names.py +0 -0
  26. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/play_local_file_lists.py +0 -0
  27. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/sonos.py +0 -0
  28. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/sonos_discover.py +0 -0
  29. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/speaker_info.py +0 -0
  30. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/track_follow.py +0 -0
  31. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/utils.py +0 -0
  32. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli/wait_actions.py +0 -0
  33. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli.egg-info/SOURCES.txt +0 -0
  34. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli.egg-info/dependency_links.txt +0 -0
  35. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli.egg-info/entry_points.txt +0 -0
  36. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli.egg-info/requires.txt +0 -0
  37. {soco-cli-0.4.73 → soco-cli-0.4.75}/soco_cli.egg-info/top_level.txt +0 -0
  38. {soco-cli-0.4.73 → soco-cli-0.4.75}/tests/test_cli.py +0 -0
  39. {soco-cli-0.4.73 → soco-cli-0.4.75}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: soco-cli
3
- Version: 0.4.73
3
+ Version: 0.4.75
4
4
  Summary: Sonos command line control utility, based on SoCo
5
5
  Author-email: Avantrec Ltd <soco_cli@avantrec.com>
6
6
  Project-URL: Homepage, https://github.com/avantrec/soco-cli
@@ -10,4 +10,4 @@ server, to control Sonos via HTTP requests.
10
10
  For more information, please see: https://github.com/avantrec/soco-cli
11
11
  """
12
12
 
13
- __version__ = "0.4.73"
13
+ __version__ = "0.4.75"
@@ -53,20 +53,18 @@ def list_alarms(speaker, action, args, soco_function, use_local_speaker_list):
53
53
  duration = alarm.duration.strftime("%H:%M")
54
54
  else:
55
55
  duration = "No Limit"
56
- details.append(
57
- [
58
- alarm.alarm_id,
59
- alarm.zone.player_name,
60
- time,
61
- duration,
62
- alarm.recurrence,
63
- convert_true_false(alarm.enabled),
64
- title,
65
- alarm.play_mode,
66
- alarm.volume,
67
- convert_true_false(alarm.include_linked_zones),
68
- ]
69
- )
56
+ details.append([
57
+ alarm.alarm_id,
58
+ alarm.zone.player_name,
59
+ time,
60
+ duration,
61
+ alarm.recurrence,
62
+ convert_true_false(alarm.enabled),
63
+ title,
64
+ alarm.play_mode,
65
+ alarm.volume,
66
+ convert_true_false(alarm.include_linked_zones),
67
+ ])
70
68
 
71
69
  # Sort alarms by start time, room. Apply sorts in reverse order.
72
70
  details.sort(key=lambda field: field[1]) # Room
@@ -1,6 +1,7 @@
1
1
  """Plays files from the local filesystem."""
2
2
 
3
3
  import functools
4
+ import http.client
4
5
  import logging
5
6
  import sys
6
7
  import time
@@ -10,7 +11,7 @@ from ipaddress import IPv4Address, IPv4Network
10
11
  from os import chdir, path
11
12
  from socketserver import ThreadingMixIn
12
13
  from threading import Thread
13
- from typing import List, Union
14
+ from typing import List, Optional
14
15
 
15
16
  import ifaddr # type: ignore
16
17
  from RangeHTTPServer import RangeRequestHandler # type: ignore
@@ -93,7 +94,7 @@ class MyHTTPHandler(RangeRequestHandler):
93
94
 
94
95
  def http_server(
95
96
  server_ip: str, directory: str, filename: str, speaker_ips: List[str]
96
- ) -> Union[ThreadedHTTPServer, None]:
97
+ ) -> Optional[ThreadedHTTPServer]:
97
98
  # Set the directory from which to serve files, in the handler
98
99
  # Set the specific filename and client IP that are authorised
99
100
  handler = functools.partial(
@@ -122,18 +123,48 @@ def http_server(
122
123
  return None
123
124
 
124
125
 
125
- def get_server_ip(speaker: SoCo) -> Union[str, None]:
126
- # Get a suitable IP address to use as a server address for Sonos
127
- # on this host
126
+ def get_server_ip(speaker: SoCo) -> Optional[str]:
127
+ # Get the host IP address to use as a server IP for Sonos
128
+ # on this host.
129
+
128
130
  adapters = ifaddr.get_adapters()
131
+
132
+ # First, try to find a host IP address in the same network as the speaker
129
133
  for adapter in adapters:
130
134
  for ip in adapter.ips:
131
- if ip.is_IPv4:
135
+ if ip.is_IPv4 and ip.ip != "127.0.0.1":
136
+ logging.info(
137
+ "Checking if IP address '{}' is in target speaker's network".format(
138
+ ip.ip
139
+ )
140
+ )
132
141
  network = IPv4Network(
133
142
  ip.ip + "/" + str(ip.network_prefix), strict=False
134
143
  )
135
144
  if IPv4Address(speaker.ip_address) in network:
136
145
  return ip.ip
146
+
147
+ # If that fails, try to find a host IP address that can reach the target speaker
148
+ for adapter in adapters:
149
+ for ip in adapter.ips:
150
+ if ip.is_IPv4 and ip.ip != "127.0.0.1":
151
+ try:
152
+ logging.info(
153
+ "Checking target speaker's reachability from IP address '{}'"
154
+ .format(ip.ip)
155
+ )
156
+ http_connection = http.client.HTTPConnection(
157
+ speaker.ip_address,
158
+ port=1400,
159
+ timeout=0.5,
160
+ source_address=(ip.ip, PORT_END),
161
+ )
162
+ http_connection.request("GET", "/status/info")
163
+ if http_connection.getresponse().status == 200:
164
+ return ip.ip
165
+ except:
166
+ continue
167
+
137
168
  return None
138
169
 
139
170
 
@@ -186,7 +217,6 @@ def is_supported_type(filename: str) -> bool:
186
217
  file_upper = filename.upper()
187
218
  for file_type in SUPPORTED_TYPES:
188
219
  if file_upper.endswith("." + file_type):
189
- # Supported file type
190
220
  return True
191
221
  return False
192
222
 
@@ -305,15 +305,13 @@ class Speakers:
305
305
  visible = "Visible"
306
306
  else:
307
307
  visible = "Hidden"
308
- households[device.household_id].append(
309
- (
310
- device.speaker_name,
311
- device.ip_address,
312
- device.model_name.replace("Sonos ", ""),
313
- visible,
314
- device.display_version,
315
- )
316
- )
308
+ households[device.household_id].append((
309
+ device.speaker_name,
310
+ device.ip_address,
311
+ device.model_name.replace("Sonos ", ""),
312
+ visible,
313
+ device.display_version,
314
+ ))
317
315
  num_devices += 1
318
316
 
319
317
  headers = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: soco-cli
3
- Version: 0.4.73
3
+ Version: 0.4.75
4
4
  Summary: Sonos command line control utility, based on SoCo
5
5
  Author-email: Avantrec Ltd <soco_cli@avantrec.com>
6
6
  Project-URL: Homepage, https://github.com/avantrec/soco-cli
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes