Skip to content

Commit 3a95f55

Browse files
authored
Merge pull request #410 from pkkid/new_hubs
new_hubs
2 parents f371061 + ba1559d commit 3a95f55

File tree

3 files changed

+77
-9
lines changed

3 files changed

+77
-9
lines changed

plexapi/library.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ def _loadData(self, data):
10011001
self.size = utils.cast(int, data.attrib.get('size'))
10021002
self.title = data.attrib.get('title')
10031003
self.type = data.attrib.get('type')
1004+
self.key = data.attrib.get('key')
10041005
self.items = self.findItems(data)
10051006

10061007
def __len__(self):

plexapi/myplex.py

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
# -*- coding: utf-8 -*-
22
import copy
3-
import requests
43
import time
5-
from requests.status_codes import _codes as codes
6-
from plexapi import BASE_HEADERS, CONFIG, TIMEOUT, X_PLEX_IDENTIFIER, X_PLEX_ENABLE_FAST_CONNECT
7-
from plexapi import log, logfilter, utils
4+
5+
import requests
6+
from plexapi import (BASE_HEADERS, CONFIG, TIMEOUT, X_PLEX_ENABLE_FAST_CONNECT,
7+
X_PLEX_IDENTIFIER, log, logfilter, utils)
88
from plexapi.base import PlexObject
99
from plexapi.exceptions import BadRequest, NotFound, Unauthorized
1010
from plexapi.client import PlexClient
1111
from plexapi.compat import ElementTree
1212
from plexapi.library import LibrarySection
1313
from plexapi.server import PlexServer
14-
from plexapi.sync import SyncList, SyncItem
14+
from plexapi.sync import SyncItem, SyncList
1515
from plexapi.utils import joinArgs
16+
from requests.status_codes import _codes as codes
1617

1718

1819
class MyPlexAccount(PlexObject):
@@ -73,6 +74,12 @@ class MyPlexAccount(PlexObject):
7374
REQUESTS = 'https://plex.tv/api/invites/requests' # get
7475
SIGNIN = 'https://plex.tv/users/sign_in.xml' # get with auth
7576
WEBHOOKS = 'https://plex.tv/api/v2/user/webhooks' # get, post with data
77+
# Hub sections
78+
VOD = 'https://vod.provider.plex.tv/' # get
79+
WEBSHOWS = 'https://webshows.provider.plex.tv/' # get
80+
NEWS = 'https://news.provider.plex.tv/' # get
81+
PODCASTS = 'https://podcasts.provider.plex.tv/' # get
82+
MUSIC = 'https://music.provider.plex.tv/' # get
7683
# Key may someday switch to the following url. For now the current value works.
7784
# https://plex.tv/api/v2/user?X-Plex-Token={token}&X-Plex-Client-Identifier={clientId}
7885
key = 'https://plex.tv/users/account'
@@ -388,8 +395,8 @@ def updateFriend(self, user, server, sections=None, removeSections=False, allowS
388395
params = {'server_id': machineId, 'shared_server': {'library_section_ids': sectionIds}}
389396
url = self.FRIENDSERVERS.format(machineId=machineId, serverId=serverId)
390397
else:
391-
params = {'server_id': machineId, 'shared_server': {'library_section_ids': sectionIds,
392-
'invited_id': user.id}}
398+
params = {'server_id': machineId,
399+
'shared_server': {'library_section_ids': sectionIds, 'invited_id': user.id}}
393400
url = self.FRIENDINVITE.format(machineId=machineId)
394401
# Remove share sections, add shares to user without shares, or update shares
395402
if not user_servers or sectionIds:
@@ -433,7 +440,7 @@ def user(self, username):
433440
return user
434441

435442
elif (user.username and user.email and user.id and username.lower() in
436-
(user.username.lower(), user.email.lower(), str(user.id))):
443+
(user.username.lower(), user.email.lower(), str(user.id))):
437444
return user
438445

439446
raise NotFound('Unable to find user %s' % username)
@@ -617,6 +624,41 @@ def history(self, maxresults=9999999, mindate=None):
617624
hist.extend(conn.history(maxresults=maxresults, mindate=mindate, accountID=1))
618625
return hist
619626

627+
def videoOnDemand(self):
628+
""" Returns a list of VOD Hub items :class:`~plexapi.library.Hub`
629+
"""
630+
req = requests.get(self.VOD + 'hubs/', headers={'X-Plex-Token': self._token})
631+
elem = ElementTree.fromstring(req.text)
632+
return self.findItems(elem)
633+
634+
def webShows(self):
635+
""" Returns a list of Webshow Hub items :class:`~plexapi.library.Hub`
636+
"""
637+
req = requests.get(self.WEBSHOWS + 'hubs/', headers={'X-Plex-Token': self._token})
638+
elem = ElementTree.fromstring(req.text)
639+
return self.findItems(elem)
640+
641+
def news(self):
642+
""" Returns a list of News Hub items :class:`~plexapi.library.Hub`
643+
"""
644+
req = requests.get(self.NEWS + 'hubs/sections/all', headers={'X-Plex-Token': self._token})
645+
elem = ElementTree.fromstring(req.text)
646+
return self.findItems(elem)
647+
648+
def podcasts(self):
649+
""" Returns a list of Podcasts Hub items :class:`~plexapi.library.Hub`
650+
"""
651+
req = requests.get(self.PODCASTS + 'hubs/', headers={'X-Plex-Token': self._token})
652+
elem = ElementTree.fromstring(req.text)
653+
return self.findItems(elem)
654+
655+
def tidal(self):
656+
""" Returns a list of tidal Hub items :class:`~plexapi.library.Hub`
657+
"""
658+
req = requests.get(self.MUSIC + 'hubs/', headers={'X-Plex-Token': self._token})
659+
elem = ElementTree.fromstring(req.text)
660+
return self.findItems(elem)
661+
620662

621663
class MyPlexUser(PlexObject):
622664
""" This object represents non-signed in users such as friends and linked

plexapi/video.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ def download(self, savepath=None, keep_original_name=False, **kwargs):
352352
else:
353353
self._server.url('%s?download=1' % location.key)
354354
filepath = utils.download(url, self._server._token, filename=name,
355-
savepath=savepath, session=self._server._session)
355+
savepath=savepath, session=self._server._session)
356356
if filepath:
357357
filepaths.append(filepath)
358358
return filepaths
@@ -722,3 +722,28 @@ def show(self):
722722
def _defaultSyncTitle(self):
723723
""" Returns str, default title for a new syncItem. """
724724
return '%s - %s - (%s) %s' % (self.grandparentTitle, self.parentTitle, self.seasonEpisode, self.title)
725+
726+
727+
@utils.registerPlexObject
728+
class Clip(Playable, Video):
729+
""" Represents a single Clip."""
730+
731+
TAG = 'Video'
732+
TYPE = 'clip'
733+
METADATA_TYPE = 'clip'
734+
735+
def _loadData(self, data):
736+
self._data = data
737+
self.addedAt = data.attrib.get('addedAt')
738+
self.duration = data.attrib.get('duration')
739+
self.guid = data.attrib.get('guid')
740+
self.key = data.attrib.get('key')
741+
self.originallyAvailableAt = data.attrib.get('originallyAvailableAt')
742+
self.ratingKey = data.attrib.get('ratingKey')
743+
self.skipDetails = utils.cast(int, data.attrib.get('skipDetails'))
744+
self.subtype = data.attrib.get('subtype')
745+
self.thumb = data.attrib.get('thumb')
746+
self.thumbAspectRatio = data.attrib.get('thumbAspectRatio')
747+
self.title = data.attrib.get('title')
748+
self.type = data.attrib.get('type')
749+
self.year = data.attrib.get('year')

0 commit comments

Comments
 (0)