@@ -98,27 +98,87 @@ def _defaultSyncTitle(self):
9898 return self .title
9999
100100 def uploadSubtitles (self , filepath ):
101- """ Upload Subtitle file for video. """
101+ """ Upload a subtitle file for the video.
102+
103+ Parameters:
104+ filepath (str): Path to subtitle file.
105+ """
102106 url = f'{ self .key } /subtitles'
103107 filename = os .path .basename (filepath )
104108 subFormat = os .path .splitext (filepath )[1 ][1 :]
109+ params = {
110+ 'title' : filename ,
111+ 'format' : subFormat ,
112+ }
113+ headers = {'Accept' : 'text/plain, */*' }
105114 with open (filepath , 'rb' ) as subfile :
106- params = {'title' : filename ,
107- 'format' : subFormat
108- }
109- headers = {'Accept' : 'text/plain, */*' }
110115 self ._server .query (url , self ._server ._session .post , data = subfile , params = params , headers = headers )
111116 return self
112117
113- def removeSubtitles (self , streamID = None , streamTitle = None ):
114- """ Remove Subtitle from movie's subtitles listing.
118+ def searchSubtitles (self , language = 'en' , hearingImpaired = 0 , forced = 0 ):
119+ """ Search for on-demand subtitles for the video.
120+ See https://support.plex.tv/articles/subtitle-search/.
115121
116- Note: If subtitle file is located inside video directory it will bbe deleted.
117- Files outside of video directory are not effected.
122+ Parameters:
123+ language (str, optional): Language code (ISO 639-1) of the subtitles to search for.
124+ Default 'en'.
125+ hearingImpaired (int, optional): Search option for SDH subtitles.
126+ Default 0.
127+ (0 = Prefer non-SDH subtitles, 1 = Prefer SDH subtitles,
128+ 2 = Only show SDH subtitles, 3 = Only show non-SDH subtitles)
129+ forced (int, optional): Search option for forced subtitles.
130+ Default 0.
131+ (0 = Prefer non-forced subtitles, 1 = Prefer forced subtitles,
132+ 2 = Only show forced subtitles, 3 = Only show non-forced subtitles)
133+
134+ Returns:
135+ List<:class:`~plexapi.media.SubtitleStream`>: List of SubtitleStream objects.
136+ """
137+ params = {
138+ 'language' : language ,
139+ 'hearingImpaired' : hearingImpaired ,
140+ 'forced' : forced ,
141+ }
142+ key = f'{ self .key } /subtitles{ utils .joinArgs (params )} '
143+ return self .fetchItems (key )
144+
145+ def downloadSubtitles (self , subtitleStream ):
146+ """ Download on-demand subtitles for the video.
147+ See https://support.plex.tv/articles/subtitle-search/.
148+
149+ Note: This method is asynchronous and returns immediately before subtitles are fully downloaded.
150+
151+ Parameters:
152+ subtitleStream (:class:`~plexapi.media.SubtitleStream`):
153+ Subtitle object returned from :func:`~plexapi.video.Video.searchSubtitles`.
154+ """
155+ key = f'{ self .key } /subtitles'
156+ params = {'key' : subtitleStream .key }
157+ self ._server .query (key , self ._server ._session .put , params = params )
158+ return self
159+
160+ def removeSubtitles (self , subtitleStream = None , streamID = None , streamTitle = None ):
161+ """ Remove an upload or downloaded subtitle from the video.
162+
163+ Note: If the subtitle file is located inside video directory it will be deleted.
164+ Files outside of video directory are not affected.
165+ Embedded subtitles cannot be removed.
166+
167+ Parameters:
168+ subtitleStream (:class:`~plexapi.media.SubtitleStream`, optional): Subtitle object to remove.
169+ streamID (int, optional): ID of the subtitle stream to remove.
170+ streamTitle (str, optional): Title of the subtitle stream to remove.
118171 """
119- for stream in self .subtitleStreams ():
120- if streamID == stream .id or streamTitle == stream .title :
121- self ._server .query (stream .key , self ._server ._session .delete )
172+ if subtitleStream is None :
173+ try :
174+ subtitleStream = next (
175+ stream for stream in self .subtitleStreams ()
176+ if streamID == stream .id or streamTitle == stream .title
177+ )
178+ except StopIteration :
179+ raise BadRequest (f"Subtitle stream with ID '{ streamID } ' or title '{ streamTitle } ' not found." ) from None
180+
181+ self ._server .query (subtitleStream .key , self ._server ._session .delete )
122182 return self
123183
124184 def optimize (self , title = '' , target = '' , deviceProfile = '' , videoQuality = None ,
0 commit comments