11# -*- coding: utf-8 -*-
22from plexapi import media , utils
33from plexapi .base import Playable , PlexPartialObject
4+ from plexapi .compat import quote_plus
45
56
67class Audio (PlexPartialObject ):
@@ -23,6 +24,9 @@ class Audio(PlexPartialObject):
2324 updatedAt (datatime): Datetime this item was updated.
2425 viewCount (int): Count of times this item was accessed.
2526 """
27+
28+ METADATA_TYPE = 'track'
29+
2630 def _loadData (self , data ):
2731 """ Load attribute values from Plex XML response. """
2832 self ._data = data
@@ -57,6 +61,46 @@ def url(self, part):
5761 """ Returns the full URL for this audio item. Typically used for getting a specific track. """
5862 return self ._server .url (part , includeToken = True ) if part else None
5963
64+ def _defaultSyncTitle (self ):
65+ """ Returns str, default title for a new syncItem. """
66+ return self .title
67+
68+ def sync (self , bitrate , client = None , clientId = None , limit = None , title = None ):
69+ """ Add current audio (artist, album or track) as sync item for specified device.
70+ See :func:`plexapi.myplex.MyPlexAccount.sync()` for possible exceptions.
71+
72+ Parameters:
73+ bitrate (int): maximum bitrate for synchronized music, better use one of MUSIC_BITRATE_* values from the
74+ module :mod:`plexapi.sync`.
75+ client (:class:`plexapi.myplex.MyPlexDevice`): sync destination, see
76+ :func:`plexapi.myplex.MyPlexAccount.sync`.
77+ clientId (str): sync destination, see :func:`plexapi.myplex.MyPlexAccount.sync`.
78+ limit (int): maximum count of items to sync, unlimited if `None`.
79+ title (str): descriptive title for the new :class:`plexapi.sync.SyncItem`, if empty the value would be
80+ generated from metadata of current media.
81+
82+ Returns:
83+ :class:`plexapi.sync.SyncItem`: an instance of created syncItem.
84+ """
85+
86+ from plexapi .sync import SyncItem , Policy , MediaSettings
87+
88+ myplex = self ._server .myPlexAccount ()
89+ sync_item = SyncItem (self ._server , None )
90+ sync_item .title = title if title else self ._defaultSyncTitle ()
91+ sync_item .rootTitle = self .title
92+ sync_item .contentType = self .listType
93+ sync_item .metadataType = self .METADATA_TYPE
94+ sync_item .machineIdentifier = self ._server .machineIdentifier
95+
96+ section = self ._server .library .sectionByID (self .librarySectionID )
97+
98+ sync_item .location = 'library://%s/item/%s' % (section .uuid , quote_plus (self .key ))
99+ sync_item .policy = Policy .create (limit )
100+ sync_item .mediaSettings = MediaSettings .createMusic (bitrate )
101+
102+ return myplex .sync (sync_item , client = client , clientId = clientId )
103+
60104
61105@utils .registerPlexObject
62106class Artist (Audio ):
@@ -225,6 +269,10 @@ def download(self, savepath=None, keep_orginal_name=False, **kwargs):
225269 filepaths += track .download (savepath , keep_orginal_name , ** kwargs )
226270 return filepaths
227271
272+ def _defaultSyncTitle (self ):
273+ """ Returns str, default title for a new syncItem. """
274+ return '%s - %s' % (self .parentTitle , self .title )
275+
228276
229277@utils .registerPlexObject
230278class Track (Audio , Playable ):
@@ -302,3 +350,7 @@ def album(self):
302350 def artist (self ):
303351 """ Return this track's :class:`~plexapi.audio.Artist`. """
304352 return self .fetchItem (self .grandparentKey )
353+
354+ def _defaultSyncTitle (self ):
355+ """ Returns str, default title for a new syncItem. """
356+ return '%s - %s - %s' % (self .grandparentTitle , self .parentTitle , self .title )
0 commit comments