Skip to content

Commit 35aea18

Browse files
authored
Merge pull request #1 from pkkid/master
Catch-up
2 parents 1e8b3ef + 6573b8b commit 35aea18

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+4244
-1303
lines changed

.coveragerc

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
[run]
2+
omit = */site-packages/plexapi/*
3+
4+
5+
16
[report]
27
exclude_lines =
38
pragma: no cover

.flake8

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Flake8 configuration
2+
# Copy or symlink this file to ~/.flake8
3+
# --------------------------------------
4+
# E128: continuation line under-indented for visual indent
5+
# E701: multiple statements on one line (colon)
6+
# E702: multiple statements on one line (semicolon)
7+
# E731: do not assign a lambda expression, use a def
8+
# W293: blank line contains whitespace
9+
# W503: line break before binary operator
10+
# W605: invalid escape sequence
11+
[flake8]
12+
ignore=E128,E701,E702,E731,W293,W503,W605
13+
exclude=compat.py
14+
max-complexity = -1
15+
max-line-length = 125
16+
show-source = True

.github/ISSUE_TEMPLATE/bug_report.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
name: bug_report
3+
about: Create a report to help us improve
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
**Describe the issue**
11+
A clear and concise description of what the issue is.
12+
13+
**Code snipppets**
14+
Add code snippet to help explain your problem.
15+
- please use markdown [Code and Syntax Highlighting](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code-and-syntax-highlighting) for code snippet
16+
17+
**Expected behavior**
18+
A clear and concise description of what you expected to happen.
19+
20+
**Enviroment (please complete the following information):**
21+
- OS: [e.g. Linux, Windows, Docker]
22+
- Plex version [eg. version 1.19.3.2852]
23+
- Python Version [e.g. 2.7.15, 3.6]
24+
- PlexAPI version [e.g. 3.6.0]
25+
26+
**Additional context**
27+
Add any other context about the issue here.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## Description
2+
3+
Please include a summary of the change and which issue is fixed.
4+
5+
Fixes # (issue)
6+
7+
## Type of change
8+
9+
Please delete options that are not relevant.
10+
11+
- [ ] Bug fix (non-breaking change which fixes an issue)
12+
- [ ] New feature (non-breaking change which adds functionality)
13+
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
14+
- [ ] This change requires a documentation update
15+
16+
17+
## Checklist:
18+
19+
- [ ] My code follows the style guidelines of this project
20+
- [ ] I have performed a self-review of my own code
21+
- [ ] I have commented my code, particularly in hard-to-understand areas
22+
- [ ] I have added or updated the docstring for new or existing methods
23+
- [ ] I have added tests when applicable

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ config.ini
1818
ipython_config.py
1919
dist
2020
docs/_build/
21+
docs/src/
2122
htmlcov
2223
include/
2324
lib/
2425
pip-selfcheck.json
25-
pyvenv.cfg
26+
pyvenv.cfg
27+
MANIFEST

.readthedocs.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# .readthedocs.yml
2+
3+
version: 2
4+
5+
build:
6+
image: latest
7+
8+
sphinx:
9+
configuration: docs/conf.py
10+
11+
formats: all
12+
13+
python:
14+
version: 3.7
15+
install:
16+
- requirements: requirements_dev.txt
17+
- method: pip
18+
path: .
19+
20+
system_packages: true
21+

.travis.yml

+11-8
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,13 @@ language: python
22

33
stages:
44
- test
5-
- name: deploy
6-
if: tag = present
5+
- deploy
76

87
sudo: required
98
services:
109
- docker
1110

1211
python:
13-
- 2.7
14-
- 3.4
1512
- 3.6
1613

1714
env:
@@ -23,8 +20,10 @@ env:
2320
before_install:
2421
- pip install --upgrade pip
2522
- pip install --upgrade setuptools
26-
- pip install --upgrade pytest pytest-cov coveralls
2723
install:
24+
- pip install .
25+
- python -c "import plexapi; print('installation ok')"
26+
- pip install --upgrade pytest pytest-cov coveralls
2827
- pip install -r requirements_dev.txt
2928
- '[ -z "${PLEXAPI_AUTH_MYPLEX_USERNAME}" ] && PYTHONPATH="$PWD:$PYTHONPATH" python -u tools/plex-bootstraptest.py
3029
--destination plex --advertise-ip=127.0.0.1 --bootstrap-timeout 540 --docker-tag $PLEX_CONTAINER_TAG --unclaimed ||
@@ -43,6 +42,10 @@ after_success:
4342
after_script:
4443
- '[ -z "${PLEXAPI_AUTH_MYPLEX_USERNAME}" ] || PYTHONPATH="$PWD:$PYTHONPATH" python -u tools/plex-teardowntest.py'
4544

45+
46+
notifications:
47+
webhooks: https://coveralls.io/webhook
48+
4649
jobs:
4750
include:
4851
- python: 3.6
@@ -56,7 +59,7 @@ jobs:
5659
- stage: test
5760
python: 3.6
5861
env:
59-
- PLEX_CONTAINER_TAG=1.10.1.4602-f54242b6b
62+
- PLEX_CONTAINER_TAG=latest
6063
- TEST_ACCOUNT_ONCE=1
6164
- stage: test
6265
python: 3.6
@@ -73,8 +76,8 @@ jobs:
7376
- PLEX_CONTAINER_TAG=latest
7477
deploy:
7578
provider: pypi
76-
user: mjs7231
79+
user: hellowlol
7780
password:
78-
secure: UhuEN9GAp9zMEXdVTxSrbhfYf4HjTcj47l093Qh1HYKmZACxJM/+JkQCm7+oHPJpo7YDLk2we9oEsQ41maZBr9WgZI1lwR6m590M12vPhPI7NCVzINxJqebc0uZhCFsAFFKA3kzpRQbDfsBUG4yL/AzeMcvJMgIg3m07KRVhBywnnRhQ77trbBI0Io5MBzfW9PYDeGJqlNDBM7SbB4tK0udGZQT9wmFwvIoJODPDnM15Ry4vpkVNww/vVgyHklmnYlPzQgvhSMOXk0+MWlYtaKmu6uuLAiRccT1Fsmi1POKuFEq8S0Z7w4LmwxCVRaCvsZdNW5eXWgPDhZXNcLrKMwjgJt9Vj3VcD+NCywux/C1hTq7tecBocA13kzbgg4fd2sATOjQT5iaRPGrDtKm8e00hxr125n0StDxXdYGl2W5sH0LCkZE6Vq1GjXYjKFXZeTk3Fzav/3N8IxHBX3CliJB/vbloJ2mpz1kXL4UTORl9pghPyGOOq2yJPYSSWly/RsAD7UDrL1/lezaPSJGKbZJ0CMyfA83kd82/hgZflOuBuTcPHCZSU3zMCs0fsImZZxr6Qm1tbff+iyNS/ufoYgeVfsWhlEl9FoLv1g4HG6oA+uDHz+jKz9uSRHcGqD6P4JJK+H+yy0PeYfo7b6eSqFxgt8q8QfifUaCrVoCiY+c=
81+
secure: cwMf16s+PxIUjt6/pKE7KeQPsWg4Atf9JvipkLTjx1VrVBilSjrZ7fkSDDjglkz4sCynw5/fzQRkBWqLdyqPigwKICYbpc6QWwvR+WWQLfe04zl+d4AmDljN2rtNkThlpH2qKNaFX7Up3AAcTf+GtQ7weAAyjMyJaiWBTFcgc2eBMDgEkS3bhiF4qdbfdAYbHVurJwCWXfHjkIiBJxDHA15cQRhJpkqQGIYzAst6ZwEr/Aw9FwqfC3lvFM3uIQ7sfFa/UdIesQZ50IT//roI1bvTg2T4gAMRYMs09jFm1E5mnPn4qxvK2hzsiNNesw3wSXhCehJFym8cO5jX+EYnfNJuWJtappIZeJGKldVC2g2v3PNWhmqbbKnyc446rkPtjVQqrSSUjPNOhTG61n872JVnizopo8ISDAtceSoC/mySItzjRQnRDrelkhHdV33WSyOsJKTw0H2LzjZDQRxxTqABmmCwzn7h+ycQ2Xk2INu9gt0hgIOco6Lt6VeoDMXhD6wAGDAaD7XBQwD/JSbGZns3VIgoLMxyHda9S6UeDmwwoAWhHM0mbzt0L618R+7CK0E+3vQ2k2Ee23tKIOq7DvZMpmLLjUE3wlckoKCPDrgP7Tuf5nUoz6kWv3Hxsb0wZCuVO0npSCFx+JOSQ6/7ONU4eh3hvjnnb6vqAgKqQ80=
7982
on:
8083
tags: true

README.rst

+65-31
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ Python-PlexAPI
66
:target: https://travis-ci.org/pkkid/python-plexapi
77
.. image:: https://coveralls.io/repos/github/pkkid/python-plexapi/badge.svg?branch=master
88
:target: https://coveralls.io/github/pkkid/python-plexapi?branch=master
9+
.. image:: https://img.shields.io/github/tag/pkkid/python-plexapi.svg?label=github+release
10+
:target: https://github.com/pkkid/python-plexapi/releases
11+
.. image:: https://badge.fury.io/py/PlexAPI.svg
12+
:target: https://badge.fury.io/py/PlexAPI
13+
.. image:: https://img.shields.io/github/last-commit/pkkid/python-plexapi.svg
14+
:target: https://img.shields.io/github/last-commit/pkkid/python-plexapi.svg
915

1016

1117
Overview
@@ -15,7 +21,7 @@ Plex Web Client. A few of the many features we currently support are:
1521

1622
* Navigate local or remote shared libraries.
1723
* Perform library actions such as scan, analyze, empty trash.
18-
* Remote control and play media on connected clients.
24+
* Remote control and play media on connected clients, including `Controlling Sonos speakers`_
1925
* Listen in on all Plex Server notifications.
2026

2127

@@ -118,48 +124,76 @@ Usage Examples
118124
119125
.. code-block:: python
120126
121-
# Example 8: Get a URL to stream a movie or show in another client
122-
die_hard = plex.library.section('Movies').get('Elephants Dream')
123-
print('Run running the following command to play in VLC:')
124-
print('vlc "%s"' % die_hard.getStreamURL(videoResolution='800x600'))
127+
# Example 8: Get audio/video/all playlists
128+
for playlist in plex.playlists():
129+
print(playlist.title)
125130
126131
127132
.. code-block:: python
128133
129-
# Example 9: Get audio/video/all playlists
130-
for playlist in plex.playlists():
131-
print(playlist.title)
134+
# Example 9: Rate the 100 four stars.
135+
plex.library.section('TV Shows').get('The 100').rate(8.0)
136+
137+
138+
Controlling Sonos speakers
139+
--------------------------
140+
141+
To control Sonos speakers directly using Plex APIs, the following requirements must be met:
142+
143+
1. Active Plex Pass subscription
144+
2. Sonos account linked to Plex account
145+
3. Plex remote access enabled
146+
147+
Due to the design of Sonos music services, the API calls to control Sonos speakers route through https://sonos.plex.tv
148+
and back via the Plex server's remote access. Actual media playback is local unless networking restrictions prevent the
149+
Sonos speakers from connecting to the Plex server directly.
150+
151+
.. code-block:: python
152+
153+
from plexapi.myplex import MyPlexAccount
154+
from plexapi.server import PlexServer
155+
156+
baseurl = 'http://plexserver:32400'
157+
token = '2ffLuB84dqLswk9skLos'
158+
159+
account = MyPlexAccount(token)
160+
server = PlexServer(baseurl, token)
161+
162+
# List available speakers/groups
163+
for speaker in account.sonos_speakers():
164+
print(speaker.title)
165+
166+
# Obtain PlexSonosPlayer instance
167+
speaker = account.sonos_speaker("Kitchen")
168+
169+
album = server.library.section('Music').get('Stevie Wonder').album('Innervisions')
170+
171+
# Speaker control examples
172+
speaker.playMedia(album)
173+
speaker.pause()
174+
speaker.setVolume(10)
175+
speaker.skipNext()
132176
133177
134178
Running tests over PlexAPI
135179
--------------------------
136180

137-
In order to test the PlexAPI library you have to prepare a Plex Server instance with following libraries:
138-
139-
1. Movies section (agent `com.plexapp.agents.imdb`) containing both movies:
140-
* Sintel - https://durian.blender.org/
141-
* Elephants Dream - https://orange.blender.org/
142-
* Sita Sings the Blues - http://www.sitasingstheblues.com/
143-
* Big Buck Bunny - https://peach.blender.org/
144-
2. TV Show section (agent `com.plexapp.agents.thetvdb`) containing the shows:
145-
* Game of Thrones (Season 1 and 2)
146-
* The 100 (Seasons 1 and 2)
147-
* (or symlink the above movies with proper names)
148-
3. Music section (agent `com.plexapp.agents.lastfm`) containing the albums:
149-
* Infinite State - Unmastered Impulses - https://github.com/kennethreitz/unmastered-impulses
150-
* Broke For Free - Layers - http://freemusicarchive.org/music/broke_for_free/Layers/
151-
4. A Photos section (any agent) containing the photoalbums (photoalbum is just a folder on your disk):
152-
* `Cats`
153-
* Within `Cats` album you need to place 3 photos (cute cat photos, of course)
154-
* Within `Cats` album you should place 3 more photoalbums (one of them should be named `Cats in bed`,
155-
names of others doesn't matter)
156-
* Within `Cats in bed` you need to place 7 photos
157-
* Within other 2 albums you should place 1 photo in each
158-
159-
Instead of manual creation of the library you could use a script `tools/plex-boostraptest.py` with appropriate
181+
Use:
182+
183+
.. code-block:: bash
184+
185+
tools/plex-boostraptest.py
186+
187+
with appropriate
160188
arguments and add this new server to a shared user which username is defined in environment veriable `SHARED_USERNAME`.
161189
It uses `official docker image`_ to create a proper instance.
162190

191+
For skipping the docker and reuse a existing server use
192+
193+
.. code-block:: bash
194+
195+
python plex-boostraptest.py --no-docker -username USERNAME --password PASSWORD --server-name NAME-OF-YOUR-SEVER
196+
163197
Also in order to run most of the tests you have to provide some environment variables:
164198

165199
* `PLEXAPI_AUTH_SERVER_BASEURL` containing an URL to your Plex instance, e.g. `http://127.0.0.1:32400` (without trailing

docs/conf.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ def new_resolve_xref(*args):
6060
# You can specify multiple suffix as a list of string:
6161
# source_suffix = ['.rst', '.md']
6262
# source_suffix = '.rst'
63-
source_parsers = {'.md': CommonMarkParser}
64-
source_suffix = ['.rst', '.md']
63+
# source_parsers = {'.md': CommonMarkParser} # deprecated
64+
# source_suffix = ['.rst', '.md'] # deprecated
6565

6666
# The encoding of source files.
6767
# source_encoding = 'utf-8-sig'

docs/modules/gdm.rst

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. include:: ../global.rst
2+
3+
Gdm :modname:`plexapi.gdm`
4+
--------------------------------
5+
.. automodule:: plexapi.gdm
6+
:members:
7+
:show-inheritance:

docs/modules/sonos.rst

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. include:: ../global.rst
2+
3+
Sonos :modname:`plexapi.sonos`
4+
--------------------------------
5+
.. automodule:: plexapi.sonos
6+
:members:
7+
:show-inheritance:

docs/toc.rst

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
modules/client
1818
modules/config
1919
modules/exceptions
20+
modules/gdm
2021
modules/library
2122
modules/media
2223
modules/myplex
@@ -25,6 +26,8 @@
2526
modules/playqueue
2627
modules/server
2728
modules/settings
29+
modules/sonos
2830
modules/sync
2931
modules/utils
3032
modules/video
33+

package.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"scripts": {
3+
"pypi": "python setup.py sdist upload"
4+
}
5+
}

plexapi/__init__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
import os
44
from logging.handlers import RotatingFileHandler
55
from platform import uname
6+
from uuid import getnode
7+
68
from plexapi.config import PlexConfig, reset_base_headers
79
from plexapi.utils import SecretsFilter
8-
from uuid import getnode
910

1011
# Load User Defined Config
1112
DEFAULT_CONFIG_PATH = os.path.expanduser('~/.config/plexapi/config.ini')
@@ -14,7 +15,7 @@
1415

1516
# PlexAPI Settings
1617
PROJECT = 'PlexAPI'
17-
VERSION = '3.1.0'
18+
VERSION = '4.0.0'
1819
TIMEOUT = CONFIG.get('plexapi.timeout', 30, int)
1920
X_PLEX_CONTAINER_SIZE = CONFIG.get('plexapi.container_size', 100, int)
2021
X_PLEX_ENABLE_FAST_CONNECT = CONFIG.get('plexapi.enable_fast_connect', False, bool)

0 commit comments

Comments
 (0)