[Python-modules-commits] [python-soco] 01/07: import soco_0.12.orig.tar.gz

Ruben Undheim rubund-guest at moszumanska.debian.org
Tue Dec 13 18:37:30 UTC 2016


This is an automated email from the git hooks/post-receive script.

rubund-guest pushed a commit to branch master
in repository python-soco.

commit 8249c94b02bec986251eeb8819fb79a44472dcd1
Author: Ruben Undheim <ruben.undheim at gmail.com>
Date:   Sun Dec 11 19:23:14 2016 +0100

    import soco_0.12.orig.tar.gz
---
 AUTHORS.rst                                        |   36 +
 LICENSE.rst                                        |   22 +
 MANIFEST.in                                        |   24 +
 PKG-INFO                                           |  242 +++
 README.rst                                         |  217 +++
 dev_tools/analyse_ws.ini                           |    2 +
 dev_tools/analyse_ws.py                            |  530 ++++++
 dev_tools/pychecker.bat                            |    6 +
 dev_tools/pychecker.sh                             |   17 +
 dev_tools/sonosdump.py                             |   72 +
 doc/Makefile                                       |  192 ++
 doc/_static/imageMapResizer.min.js                 |    8 +
 doc/_templates/page.html                           |   23 +
 doc/advanced/data-structures-mod.rst               |   49 +
 doc/advanced/events.rst                            |   54 +
 doc/advanced/index.rst                             |    7 +
 doc/advanced/services.rst                          |   43 +
 doc/advanced/topology.rst                          |   60 +
 doc/api/soco.alarms.rst                            |    4 +
 doc/api/soco.cache.rst                             |    7 +
 doc/api/soco.compat.rst                            |    4 +
 doc/api/soco.config.rst                            |    4 +
 doc/api/soco.core.rst                              |    4 +
 doc/api/soco.data_structures.rst                   |    4 +
 doc/api/soco.discovery.rst                         |    4 +
 doc/api/soco.events.rst                            |    4 +
 doc/api/soco.exceptions.rst                        |    4 +
 doc/api/soco.groups.rst                            |    4 +
 doc/api/soco.ms_data_structures.rst                |    4 +
 doc/api/soco.music_library.rst                     |    4 +
 doc/api/soco.music_services.accounts.rst           |    4 +
 doc/api/soco.music_services.music_service.rst      |    4 +
 doc/api/soco.music_services.rst                    |   11 +
 doc/api/soco.plugins.example.rst                   |    4 +
 doc/api/soco.plugins.rst                           |   16 +
 doc/api/soco.plugins.spotify.rst                   |    4 +
 doc/api/soco.plugins.wimp.rst                      |    4 +
 doc/api/soco.rst                                   |   35 +
 doc/api/soco.services.rst                          |    4 +
 doc/api/soco.snapshot.rst                          |    4 +
 doc/api/soco.soap.rst                              |    4 +
 doc/api/soco.utils.rst                             |    4 +
 doc/api/soco.xml.rst                               |    4 +
 doc/authors.rst                                    |    7 +
 doc/conf.py                                        |  397 ++++
 doc/development/index.rst                          |    8 +
 doc/development/release-howto.rst                  |   64 +
 doc/development/unittests.rst                      |  227 +++
 doc/examples.rst                                   |  115 ++
 doc/getting_started.rst                            |  115 ++
 doc/graphics/data_structures.png                   |  Bin 0 -> 76169 bytes
 doc/graphics/data_structures.svg                   | 1273 +++++++++++++
 doc/index.rst                                      |   89 +
 doc/make.bat                                       |  263 +++
 doc/plugins.rst                                    |   58 +
 doc/release_notes.rst                              |   11 +
 doc/releases/0.10.rst                              |   83 +
 doc/releases/0.11.1.rst                            |   16 +
 doc/releases/0.11.rst                              |   91 +
 doc/releases/0.12.rst                              |  146 ++
 doc/releases/0.6.rst                               |   41 +
 doc/releases/0.7.rst                               |  121 ++
 doc/releases/0.8.rst                               |  104 ++
 doc/releases/0.9.rst                               |   99 +
 doc/releases/index.rst                             |   17 +
 doc/tutorial.rst                                   |    8 +
 examples/commandline/README.rst                    |    4 +
 examples/commandline/discover.py                   |    7 +
 examples/commandline/screenshot.png                |  Bin 0 -> 59104 bytes
 examples/commandline/tunein.py                     |   67 +
 examples/play_local_files/play_local_files.py      |  106 ++
 examples/plugins/socoplugins.py                    |   46 +
 examples/webapp/.gitignore                         |    3 +
 examples/webapp/README.md                          |   22 +
 examples/webapp/index.py                           |   96 +
 examples/webapp/requirements.txt                   |    2 +
 examples/webapp/screenshot.png                     |  Bin 0 -> 264587 bytes
 examples/webapp/settings.py.example                |    3 +
 examples/webapp/static/css/bootstrap.min.css       |  689 +++++++
 examples/webapp/static/css/main.css                |   17 +
 examples/webapp/static/img/blank.jpg               |  Bin 0 -> 15285 bytes
 .../static/img/glyphicons-halflings-white.png      |  Bin 0 -> 4352 bytes
 .../webapp/static/img/glyphicons-halflings.png     |  Bin 0 -> 4352 bytes
 examples/webapp/static/js/bootstrap.min.js         |    6 +
 examples/webapp/static/js/jquery.min.js            |    4 +
 examples/webapp/templates/index.html               |  100 +
 makefile                                           |   22 +
 pylintrc                                           |   28 +
 requirements-dev.txt                               |   10 +
 requirements.txt                                   |    2 +
 setup.cfg                                          |   34 +
 setup.py                                           |   90 +
 soco.egg-info/PKG-INFO                             |  242 +++
 soco.egg-info/SOURCES.txt                          |  137 ++
 soco.egg-info/dependency_links.txt                 |    1 +
 soco.egg-info/requires.txt                         |    2 +
 soco.egg-info/top_level.txt                        |    1 +
 soco/__init__.py                                   |   36 +
 soco/alarms.py                                     |  319 ++++
 soco/cache.py                                      |  216 +++
 soco/compat.py                                     |   73 +
 soco/config.py                                     |   41 +
 soco/core.py                                       | 1960 ++++++++++++++++++++
 soco/data_structures.py                            | 1141 ++++++++++++
 soco/discovery.py                                  |  210 +++
 soco/events.py                                     |  611 ++++++
 soco/exceptions.py                                 |   78 +
 soco/groups.py                                     |  113 ++
 soco/ms_data_structures.py                         |  548 ++++++
 soco/music_library.py                              |  555 ++++++
 soco/music_services/__init__.py                    |   14 +
 soco/music_services/accounts.py                    |  199 ++
 soco/music_services/music_service.py               |  869 +++++++++
 soco/plugins/__init__.py                           |   45 +
 soco/plugins/example.py                            |   54 +
 soco/plugins/spotify.py                            |   34 +
 soco/plugins/wimp.py                               |  540 ++++++
 soco/services.py                                   |  798 ++++++++
 soco/snapshot.py                                   |  258 +++
 soco/soap.py                                       |  314 ++++
 soco/utils.py                                      |  188 ++
 soco/xml.py                                        |   97 +
 tests/conftest.py                                  |   24 +
 tests/soco_unittest.py                             |  458 +++++
 tests/test_alarms.py                               |   18 +
 tests/test_cache.py                                |   75 +
 tests/test_core.py                                 | 1026 ++++++++++
 tests/test_discovery.py                            |   64 +
 tests/test_events.py                               |   95 +
 tests/test_integration.py                          |  837 +++++++++
 tests/test_ms_data_structures.py                   |  341 ++++
 tests/test_musicservices.py                        |  326 ++++
 tests/test_new_datastructures.py                   |  357 ++++
 tests/test_services.py                             |  225 +++
 tests/test_singleton.py                            |   56 +
 tests/test_soap.py                                 |  135 ++
 tests/test_utils.py                                |   37 +
 tests/test_xml.py                                  |   22 +
 138 files changed, 20258 insertions(+)

diff --git a/AUTHORS.rst b/AUTHORS.rst
new file mode 100644
index 0000000..f87a698
--- /dev/null
+++ b/AUTHORS.rst
@@ -0,0 +1,36 @@
+Project Creator
+===============
+SoCo was created in 2012 at Music Hack Day Sydney by Rahim Sonawalla
+
+
+Maintainers
+===========
+
+* Lawrence Akka
+* Stefan Kögl
+* Kenneth Nielsen
+
+
+Contributors
+============
+
+(alphabetical)
+
+* Petter Aas
+* Murali Allada
+* Joel Björkman
+* Aaron Daubman
+* Johan Elmerfjord
+* David H
+* Jeff Hinrichs
+* Jeroen Idserda
+* Todd Neal
+* nixscripter
+* Kenneth Nielsen
+* Dave O'Connor
+* Dennnis O'Reilly
+* phut
+* Dan Poirier
+* Jason Ting
+* Scott G Waters
+
diff --git a/LICENSE.rst b/LICENSE.rst
new file mode 100644
index 0000000..23ff495
--- /dev/null
+++ b/LICENSE.rst
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+=====================
+
+Copyright (c) Rahim Sonawalla and individual contributors (see AUTHORS)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..e543a86
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,24 @@
+# Specifies files to be included in a python sdist
+
+# Top level directory
+include requirements.txt requirements-dev.txt
+include setup.cfg pylintrc makefile
+include *.rst
+
+# dev-tools
+recursive-include dev_tools *.ini *.py *.bat *.sh
+
+# Documentation
+
+recursive-include doc *
+recursive-exclude doc *.pyc *.pyo *.rej *.orig .DS_Store
+# We don't want any built docs
+prune doc/_build
+
+# Tests
+recursive-include tests *.py
+
+# Examples
+recursive-include examples *
+recursive-exclude examples *.pyc *.pyo *.rej *.orig .DS_Store
+
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..a1f7c24
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,242 @@
+Metadata-Version: 1.1
+Name: soco
+Version: 0.12
+Summary: SoCo (Sonos Controller) is a simple library to control Sonos speakers.
+Home-page: https://github.com/SoCo/SoCo
+Author: The SoCo-Team
+Author-email: python-soco at googlegroups.com
+License: MIT License
+Description: SoCo
+        ====
+        
+        SoCo (Sonos Controller) is a simple Python class that allows you to
+        programmatically control `Sonos speakers`_. It was originally created at `Music
+        Hack Day Sydney`_ by `Rahim Sonawalla`_ and is now developed by a `team of
+        people`_ at its `GitHub repository`_
+        
+        For more background on the project, please see Rahim's `blog post
+        <http://www.hirahim.com/blog/2012/04/29/dissecting-the-sonos-controller/>`_.
+        
+        Visit the `SoCo documentation`_ for a more detailed overview of all the functionailty.
+        
+        .. image:: https://travis-ci.org/SoCo/SoCo.svg?branch=master
+           :target: https://travis-ci.org/SoCo/SoCo
+           :alt: Build Status
+        
+        .. image:: https://img.shields.io/requires/github/SoCo/SoCo/master.svg?style=flat
+           :target: https://requires.io/github/SoCo/SoCo/requirements/?branch=master
+           :alt: Requirements Status
+        
+        .. image:: https://img.shields.io/pypi/v/soco.svg?style=flat
+            :target: https://pypi.python.org/pypi/soco/
+            :alt: Latest PyPI version
+        
+        .. image:: https://img.shields.io/pypi/dm/soco.svg?style=flat
+            :target: https://pypi.python.org/pypi/soco/
+            :alt: Number of PyPI downloads
+        
+        Installation
+        ------------
+        
+        SoCo requires Python 2.7, or 3.3 or newer.
+        
+        Use pip:
+        
+        ``pip install soco``
+        
+        
+        SoCo depends on the `Requests`_ HTTP library. If you use pip to install Soco,
+        Requests will be installed automatically for you. If not, you can use:
+        
+        ``pip install requests``
+        
+        
+        Basic Usage
+        -----------
+        
+        You can interact with a Sonos Zone Player through a SoCo object. If you know
+        the IP address of a Zone Player, you can create a SoCo object directly:
+        
+        .. code:: python
+        
+            >>> from soco import SoCo
+            >>> my_zone = SoCo('192.168.1.101')
+            >>> my_zone.player_name
+            Kitchen
+            >>> my_zone.status_light = True
+            >>> my_zone.volume = 6
+        
+        
+        But perhaps the easiest way is to use the module-level `discover` function.
+        This will find all the Zone Players on your network, and return a python
+        set containing them:
+        
+        .. code:: python
+        
+            >>> import soco
+            >>> for zone in soco.discover():
+            ...        print zone.player_name
+            Living Room
+            Kitchen
+        
+        
+        If you prefer a list to a set:
+        
+        .. code:: python
+        
+            >>> zone_list = list(soco.discover())
+            >>> zone_list
+            [SoCo("192.168.1.101"), SoCo("192.168.1.102")]
+            >>> zone_list[0].mute = True
+        
+        Of course, you can also play music!
+        
+        .. code:: python
+        
+            #!/usr/bin/env python
+            from soco import SoCo
+        
+            if __name__ == '__main__':
+                sonos = SoCo('192.168.1.102') # Pass in the IP of your Sonos speaker
+                # You could use the discover function instead, if you don't know the IP
+        
+                # Pass in a URI to a media file to have it streamed through the Sonos
+                # speaker
+                sonos.play_uri(
+                    'http://archive.org/download/TenD2005-07-16.flac16/TenD2005-07-16t10Wonderboy_64kb.mp3')
+        
+                track = sonos.get_current_track_info()
+        
+                print track['title']
+        
+                sonos.pause()
+        
+                # Play a stopped or paused track
+                sonos.play()
+        
+        
+        Example Applications
+        --------------------
+        
+        To show off what can be made with SoCo, a simple web application is included in
+        the ``examples`` folder.
+        
+        .. figure:: https://github.com/SoCo/SoCo/raw/master/examples/webapp/screenshot.png
+           :alt: Screenshot of web app
+        
+           Screenshot of web app
+        
+        
+        Features
+        --------
+        
+        SoCo supports the following controls amongst others:
+        
+        -  Play
+        -  Pause
+        -  Stop
+        -  Next track
+        -  Previous track
+        -  Get current transport information(if speaker is
+           playing,paused,stopped)
+        -  Get information about the currently playing track
+        
+           -  Track title
+           -  Artist
+           -  Album
+           -  Album Art (if available)
+           -  Track length
+           -  Duration played (for example, 30 seconds into a 3 minute song)
+           -  Playlist position (for example, item 5 in the playlist)
+           -  Track URI
+        
+        -  Mute (or unmute) the speaker
+        -  Get or set the speaker volume
+        -  Get or set the speaker’s bass EQ
+        -  Get or set the speaker’s treble EQ
+        -  Toggle the speaker’s loudness compensation
+        -  Turn on (or off) the white status light on the unit
+        -  Switch the speaker’s source to line-in or TV input (if the Zone Player
+           supports it)
+        -  Get the speaker’s information
+        
+           -  Zone Name
+           -  Zone Icon
+           -  UID (usually something like RINCON\_XXXXXXXXXXXXXXXXX)
+           -  Serial Number
+           -  Software version
+           -  Hardware version
+           -  MAC Address
+        
+        -  Set the speaker’s Zone Name
+        -  Find all the Sonos speakers in a network.
+        -  Put all Sonos speakers in a network into “party mode”.
+        -  “Unjoin” speakers from a group.
+        -  Manage the Sonos queue (get the items in it, add to it, clear it,
+           play a specific song from it)
+        -  Get the saved favorite radio stations and shows (title and stream
+           URI)
+        -  Search for and play item from your music library
+        -  Start a music library update and determine if one is in progress
+        
+        SoCo also supports lower level access from Python to all Sonos services (eg
+        Alarms)
+        
+        
+        Related Projects
+        ----------------
+        
+        Socos is a command line tool for controlling Sonos devices. It is developed
+        in conjunction with Soco, but in a `separate repository <https://github.com/SoCo/socos>`_.
+        
+        More of a Ruby fan? Not a problem, `Sam Soffes`_ is building out an
+        awesome `Ruby gem`_.
+        
+        Looking for a GUI that’s more than just a sample project? `Joel
+        Björkman`_ is building a Sonos Controller GUI–great for folks on Linux
+        where there isn’t an official Sonos Controller application! Find, fork,
+        and contribute to it here: https://github.com/labero/SoCo-Tk.
+        
+        
+        Google Group
+        ------------
+        
+        There is a Soco group over at `Google Groups`_.  Feel free to drop in.
+        
+        
+        License
+        -------
+        
+        SoCo is released under the `MIT license`_.
+        
+        
+        .. _Sonos speakers: http://www.sonos.com/system/
+        .. _Music Hack Day Sydney: http://sydney.musichackday.org/2012/
+        .. _blog post: http://www.hirahim.com/blog/2012/04/29/dissecting-the-sonos-controller/
+        .. _Requests: http://docs.python-requests.org/
+        .. _Sam Soffes: https://github.com/soffes
+        .. _Ruby gem: https://github.com/soffes/sonos
+        .. _Joel Björkman: https://github.com/labero
+        .. _MIT license: http://www.opensource.org/licenses/mit-license.php
+        .. _Rahim Sonawalla: https://github.com/rahims/SoCo
+        .. _GitHub repository: https://github.com/SoCo/SoCo
+        .. _team of people: https://github.com/SoCo/SoCo/blob/master/AUTHORS.rst
+        .. _Google Groups: https://groups.google.com/forum/#!forum/python-soco
+        .. _SoCo documentation: https://soco.readthedocs.org/en/latest/
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 3 - Alpha
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Home Automation
+Classifier: Topic :: Multimedia :: Sound/Audio
+Classifier: Topic :: Multimedia :: Sound/Audio :: Players
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..3bc27d9
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,217 @@
+SoCo
+====
+
+SoCo (Sonos Controller) is a simple Python class that allows you to
+programmatically control `Sonos speakers`_. It was originally created at `Music
+Hack Day Sydney`_ by `Rahim Sonawalla`_ and is now developed by a `team of
+people`_ at its `GitHub repository`_
+
+For more background on the project, please see Rahim's `blog post
+<http://www.hirahim.com/blog/2012/04/29/dissecting-the-sonos-controller/>`_.
+
+Visit the `SoCo documentation`_ for a more detailed overview of all the functionailty.
+
+.. image:: https://travis-ci.org/SoCo/SoCo.svg?branch=master
+   :target: https://travis-ci.org/SoCo/SoCo
+   :alt: Build Status
+
+.. image:: https://img.shields.io/requires/github/SoCo/SoCo/master.svg?style=flat
+   :target: https://requires.io/github/SoCo/SoCo/requirements/?branch=master
+   :alt: Requirements Status
+
+.. image:: https://img.shields.io/pypi/v/soco.svg?style=flat
+    :target: https://pypi.python.org/pypi/soco/
+    :alt: Latest PyPI version
+
+.. image:: https://img.shields.io/pypi/dm/soco.svg?style=flat
+    :target: https://pypi.python.org/pypi/soco/
+    :alt: Number of PyPI downloads
+
+Installation
+------------
+
+SoCo requires Python 2.7, or 3.3 or newer.
+
+Use pip:
+
+``pip install soco``
+
+
+SoCo depends on the `Requests`_ HTTP library. If you use pip to install Soco,
+Requests will be installed automatically for you. If not, you can use:
+
+``pip install requests``
+
+
+Basic Usage
+-----------
+
+You can interact with a Sonos Zone Player through a SoCo object. If you know
+the IP address of a Zone Player, you can create a SoCo object directly:
+
+.. code:: python
+
+    >>> from soco import SoCo
+    >>> my_zone = SoCo('192.168.1.101')
+    >>> my_zone.player_name
+    Kitchen
+    >>> my_zone.status_light = True
+    >>> my_zone.volume = 6
+
+
+But perhaps the easiest way is to use the module-level `discover` function.
+This will find all the Zone Players on your network, and return a python
+set containing them:
+
+.. code:: python
+
+    >>> import soco
+    >>> for zone in soco.discover():
+    ...        print zone.player_name
+    Living Room
+    Kitchen
+
+
+If you prefer a list to a set:
+
+.. code:: python
+
+    >>> zone_list = list(soco.discover())
+    >>> zone_list
+    [SoCo("192.168.1.101"), SoCo("192.168.1.102")]
+    >>> zone_list[0].mute = True
+
+Of course, you can also play music!
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from soco import SoCo
+
+    if __name__ == '__main__':
+        sonos = SoCo('192.168.1.102') # Pass in the IP of your Sonos speaker
+        # You could use the discover function instead, if you don't know the IP
+
+        # Pass in a URI to a media file to have it streamed through the Sonos
+        # speaker
+        sonos.play_uri(
+            'http://archive.org/download/TenD2005-07-16.flac16/TenD2005-07-16t10Wonderboy_64kb.mp3')
+
+        track = sonos.get_current_track_info()
+
+        print track['title']
+
+        sonos.pause()
+
+        # Play a stopped or paused track
+        sonos.play()
+
+
+Example Applications
+--------------------
+
+To show off what can be made with SoCo, a simple web application is included in
+the ``examples`` folder.
+
+.. figure:: https://github.com/SoCo/SoCo/raw/master/examples/webapp/screenshot.png
+   :alt: Screenshot of web app
+
+   Screenshot of web app
+
+
+Features
+--------
+
+SoCo supports the following controls amongst others:
+
+-  Play
+-  Pause
+-  Stop
+-  Next track
+-  Previous track
+-  Get current transport information(if speaker is
+   playing,paused,stopped)
+-  Get information about the currently playing track
+
+   -  Track title
+   -  Artist
+   -  Album
+   -  Album Art (if available)
+   -  Track length
+   -  Duration played (for example, 30 seconds into a 3 minute song)
+   -  Playlist position (for example, item 5 in the playlist)
+   -  Track URI
+
+-  Mute (or unmute) the speaker
+-  Get or set the speaker volume
+-  Get or set the speaker’s bass EQ
+-  Get or set the speaker’s treble EQ
+-  Toggle the speaker’s loudness compensation
+-  Turn on (or off) the white status light on the unit
+-  Switch the speaker’s source to line-in or TV input (if the Zone Player
+   supports it)
+-  Get the speaker’s information
+
+   -  Zone Name
+   -  Zone Icon
+   -  UID (usually something like RINCON\_XXXXXXXXXXXXXXXXX)
+   -  Serial Number
+   -  Software version
+   -  Hardware version
+   -  MAC Address
+
+-  Set the speaker’s Zone Name
+-  Find all the Sonos speakers in a network.
+-  Put all Sonos speakers in a network into “party mode”.
+-  “Unjoin” speakers from a group.
+-  Manage the Sonos queue (get the items in it, add to it, clear it,
+   play a specific song from it)
+-  Get the saved favorite radio stations and shows (title and stream
+   URI)
+-  Search for and play item from your music library
+-  Start a music library update and determine if one is in progress
+
+SoCo also supports lower level access from Python to all Sonos services (eg
+Alarms)
+
+
+Related Projects
+----------------
+
+Socos is a command line tool for controlling Sonos devices. It is developed
+in conjunction with Soco, but in a `separate repository <https://github.com/SoCo/socos>`_.
+
+More of a Ruby fan? Not a problem, `Sam Soffes`_ is building out an
+awesome `Ruby gem`_.
+
+Looking for a GUI that’s more than just a sample project? `Joel
+Björkman`_ is building a Sonos Controller GUI–great for folks on Linux
+where there isn’t an official Sonos Controller application! Find, fork,
+and contribute to it here: https://github.com/labero/SoCo-Tk.
+
+
+Google Group
+------------
+
+There is a Soco group over at `Google Groups`_.  Feel free to drop in.
+
+
+License
+-------
+
+SoCo is released under the `MIT license`_.
+
+
+.. _Sonos speakers: http://www.sonos.com/system/
+.. _Music Hack Day Sydney: http://sydney.musichackday.org/2012/
+.. _blog post: http://www.hirahim.com/blog/2012/04/29/dissecting-the-sonos-controller/
+.. _Requests: http://docs.python-requests.org/
+.. _Sam Soffes: https://github.com/soffes
+.. _Ruby gem: https://github.com/soffes/sonos
+.. _Joel Björkman: https://github.com/labero
+.. _MIT license: http://www.opensource.org/licenses/mit-license.php
+.. _Rahim Sonawalla: https://github.com/rahims/SoCo
+.. _GitHub repository: https://github.com/SoCo/SoCo
+.. _team of people: https://github.com/SoCo/SoCo/blob/master/AUTHORS.rst
+.. _Google Groups: https://groups.google.com/forum/#!forum/python-soco
+.. _SoCo documentation: https://soco.readthedocs.org/en/latest/
diff --git a/dev_tools/analyse_ws.ini b/dev_tools/analyse_ws.ini
new file mode 100644
index 0000000..50f57f8
--- /dev/null
+++ b/dev_tools/analyse_ws.ini
@@ -0,0 +1,2 @@
+[General]
+browser_command: epiphany {0}
diff --git a/dev_tools/analyse_ws.py b/dev_tools/analyse_ws.py
new file mode 100644
index 0000000..8f9992a
--- /dev/null
+++ b/dev_tools/analyse_ws.py
@@ -0,0 +1,530 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# pylint: disable=E0611,R0913
+
+""" Script to analyse ws dumps """
+
+import argparse
+import os
+import sys
+import math
+import textwrap
+PLATFORM = sys.platform.lower()
+if PLATFORM == 'win32':
+    import msvcrt
+    COLOR = False
+else:
+    import tty
+    import termios
+    COLOR = True
+import re
+import codecs
+import ConfigParser
+import StringIO
+try:
+    import pygments
+    from pygments.lexers import XmlLexer
+    from pygments.formatters import TerminalFormatter
+except ImportError:
+    print 'Module "pygments" could not be imported. Please install it. '\
+        'Exiting!'
+    sys.exit(100)
+try:
+    # Temporarily re-directing stderr to StringIO to prevent start-up message
+    # from rdpcap import
+    STDERR = sys.stderr
+    sys.stderr = StringIO.StringIO()
+    from scapy.all import rdpcap
+    sys.stderr = STDERR
+except ImportError:
+    print 'Module "scapy" could not be imported. Please install it. Exiting!'
+    sys.exit(101)
+try:
+    from lxml import etree
+    PARSER = etree.XMLParser(remove_blank_text=True)
+except ImportError:
+    print 'Module "lxml" could not be imported. Please install it. Exiting!'
+    sys.exit(102)
+import subprocess
+
+# Text bits that starts and ends the Sonos UPnP content
+STARTS = ['<s:Envelope', '<e:propertyset']
+ENDS = ['</s:Envelope>', '</e:propertyset>']
+
+
+class AnalyzeWS(object):
+    """ Class for analysis of WireShark dumps. Also shows the parts of the
+    WireShark dumps syntax highlighted in the terminal and/or writes them to
+    files and shows them in a browser.
+
+    The order of processing a file with this class is the following. The
+    class is initialized purely with options. All the content is added with
+    the set_file method. This method will load the ws file with rdpcap. For
+    each part in the ws file that has a load, it will look for Sonos
+    content. If such content is present one of three things will happen. If
+    it is the beginning of a Sonos message, it will initialize a WSPart. If
+    it is the middle part, it will add it to the content of the current
+    WSPart with WSPart.add_content. If it is the end, it will finalize the
+    WSPart with WSPart.finalize_content. Finalizing the WSPart will, apart
+    from closing it for writing also decode the body and parse the XML.
+
+    """
+
+    def __init__(self, args):
+        self.messages = []
+        self.args = args
+        self.output_prefix = args.output_prefix
+        try:
+            this_dir = os.path.dirname(os.path.abspath(__file__))
+            with open(os.path.join(this_dir, 'analyse_ws.ini')) as file__:
+                self.config = ConfigParser.ConfigParser()
+                self.config.readfp(file__)
+        except IOError:
+            self.config = None
+        self.pages = {}
+
+    def set_file(self, filename):
+        """ Analyse the file with the captured content """
+        # Use the file name as prefix if none is given
+        if self.output_prefix is None:
+            _, self.output_prefix = os.path.split(filename)
+        # Check if the file is present, since rdpcap will not do that
+        if not (os.path.isfile(filename) and os.access(filename, os.R_OK)):
+            print 'The file \'{0}\' is either not present or not readable. '\
+                  'Exiting!'.format(filename)
+            sys.exit(1)
+        try:
+            packets = rdpcap(filename)
+        except NameError:
+            # Due probably to a bug in rdpcap, this kind of error raises a
+            # NameError, because the exception that is tried to raise, is not
+            # defined
+            print 'The file \'{}\' is not a pcap capture file. Exiting!'\
+                .format(filename)
+            sys.exit(2)
+
+        for number, packet in enumerate(packets):
+            # See if there is a field called load
+            self._debug('\nNUMBER {0}'.format(number), no_prefix=True)
+            try:
+                # Will cause AttributeError if there is no load
+                packet.getfieldval('load')
+                # Get the full load
+                load = packet.sprintf('%TCP.payload%')
+                self._debug('PAYLOAD LENGTH {0}'.format(len(load)),
+                            no_prefix=True)
+                self._debug(load, load=True)
+                self._parse_load(load)
+            except AttributeError:
+                self._debug('LOAD EXCEPTION', no_prefix=True)
+        if len(self.messages) > 0 and not self.messages[-1].write_closed:
+            self._debug('DELETE LAST OPEN FILE')
+            del self.messages[-1]
+
+        if self.args.debug_analysis:
+            sys.exit(0)
+
+    def _parse_load(self, load):
+        """ Parse the load from a single packet """
+        # If the load is ??
+        if load in ['??']:
+            self._debug('IGNORING')
+        # If there is a start in load
+        elif any([start in load for start in STARTS]):
+            self._debug('START')
+            self.messages.append(WSPart(load, self.args))
+            # and there is also an end
+            if any([end in load for end in ENDS]):
+                self.messages[-1].finalize_content()
+                self._debug('AND END')
+        # If there is an end in load
+        elif any([end in load for end in ENDS]):
+            # If there is an open WSPart
+            if len(self.messages) > 0 and not\
+                    self.messages[-1].write_closed:
+                self._debug('END ON OPEN FILE')
+                self.messages[-1].add_content(load)
+                self.messages[-1].finalize_content()
+            # Ignore ends before start
+            else:
+                self._debug('END BUT NO OPEN FILE')
+        else:
+            # If there is an open WSPart
+            if len(self.messages) > 0 and not\
+                    self.messages[-1].write_closed:
+                self._debug('ADD TO OPEN FILE')
+                self.messages[-1].add_content(load)
+            # else ignore
+            else:
+                self._debug('NOTHING TO DO')
+
+    def _debug(self, message, load=False, no_prefix=False):
+        """ Output debug information """
+        if self.args.debug_analysis:
+            if load:
+                message = '\r\n'.join(
+                    ['# ' + line for line in message.strip().split('\r\n')]
+                )
+                print '{0}\n{1}\n{0}'.format('#' * 78, message)
+            else:
+                # If open message and no_prefix is False
+                if (len(self.messages) > 0 and not
+                        self.messages[-1].write_closed) and not no_prefix:
+                    print '--OPEN--> {0}'.format(message)
+                else:
+                    print message
+
+    def to_file_mode(self):
+        """ Write all the messages to files """
+        for message_no in range(len(self.messages)):
+            self.__to_file(message_no)
+
+    def __to_file(self, message_no):
+        """ Write a single message to file """
+        filename = self.__create_file_name(message_no)
+        try:
+            with codecs.open(filename, mode='w',
+                             encoding=self.messages[message_no].encoding)\
+                    as file__:
+                file__.write(self.messages[message_no].output)
+        except IOError as excep:
+            print 'Unable for open the file \'{0}\' for writing. The '\
+                  'following exception was raised:'.format(filename)
+            print excep
+            print 'Exiting!'
+            sys.exit(2)
+        return filename
+
+    def __create_file_name(self, message_no):
+        """ Create the filename to save to """
+        cwd = os.getcwd()
+        filename = '{0}_{1}.xml'.format(self.output_prefix, message_no)
+        return os.path.join(cwd, filename)
+
+    def to_browser_mode(self):
+        """ Write all the messages to files and open them in the browser """
+        for message_no in range(len(self.messages)):
+            self.__to_browser(message_no)
+
+    def __to_browser(self, message_no):
+        """ Write a single message to file and open the file in a
+        browser
+
+        """
+        filename = self.__to_file(message_no)
+        try:
+            command = self.config.get('General', 'browser_command')
+        except (ConfigParser.NoOptionError, AttributeError):
+            print 'Incorrect or missing .ini file. See --help.'
+            sys.exit(5)
+        command = str(command).format(filename)
+        command_list = command.split(' ')
+        try:
+            subprocess.Popen(command_list, stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        except OSError:
+            print 'Unable to execute the browsercommand:'
+            print command
+            print 'Exiting!'
+            sys.exit(21)
+
+    def interactive_mode(self):
+        """ Interactive mode """
+        if PLATFORM == 'win32':
+            # Defaulting to 80 on windows, better ideas are welcome, but the
+            # solutions I found online are rather bulky
+            height = 20
+            width = 80
+        else:
+            height, width = os.popen('stty size', 'r').read().split()
+            width = int(width)
+            height = int(height)
+
+        message_no = 0
+        page_no = 0
+        action = None
+        while action != 'q':
+            page_no = self.__update_window(width, height, message_no, page_no)
+            action = getch()
+            if action == 's':
+                # Coerce in range
+                message_no = \
+                    max(min(len(self.messages) - 1, message_no + 1), 0)
+                page_no = 0
+            elif action == 'w':
+                # Coerce in range
+                message_no = \
+                    max(min(len(self.messages) - 1, message_no - 1), 0)
+                page_no = 0
+            elif action == 'a':
+                page_no -= 1
+            elif action == 'd':
+                page_no += 1
+            elif action == 'b':
+                self.__to_browser(message_no)
+            elif action == 'f':
+                self.__to_file(message_no)
+
+    def __update_window(self, width, height, message_no, page_no):
... 20228 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-soco.git



More information about the Python-modules-commits mailing list