2017-08-13 05:50:40 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
Allows downloading a Plex media item from a local or shared library. You
|
|
|
|
may specify the item by the PlexWeb url (everything after !) or by
|
|
|
|
manually searching the items from the command line wizard.
|
|
|
|
|
|
|
|
Original contribution by lad1337.
|
|
|
|
"""
|
2017-09-26 18:11:19 +00:00
|
|
|
import argparse
|
|
|
|
import os
|
|
|
|
import re
|
2020-05-12 21:26:29 +00:00
|
|
|
from urllib.parse import unquote
|
2017-09-26 18:11:19 +00:00
|
|
|
|
2017-08-13 05:50:40 +00:00
|
|
|
from plexapi import utils
|
|
|
|
from plexapi.video import Episode, Movie, Show
|
|
|
|
|
2017-08-15 03:40:28 +00:00
|
|
|
VALID_TYPES = (Movie, Episode, Show)
|
2017-08-13 05:50:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
def search_for_item(url=None):
|
|
|
|
if url: return get_item_from_url(opts.url)
|
2017-09-26 18:11:19 +00:00
|
|
|
servers = [s for s in account.resources() if 'server' in s.provides]
|
|
|
|
server = utils.choose('Choose a Server', servers, 'name').connect()
|
2017-08-13 05:50:40 +00:00
|
|
|
query = input('What are you looking for?: ')
|
2023-08-29 03:29:39 +00:00
|
|
|
item = []
|
2017-08-15 03:40:28 +00:00
|
|
|
items = [i for i in server.search(query) if i.__class__ in VALID_TYPES]
|
2017-09-26 18:11:19 +00:00
|
|
|
items = utils.choose('Choose result', items, lambda x: '(%s) %s' % (x.type.title(), x.title[0:60]))
|
|
|
|
|
|
|
|
if not isinstance(items, list):
|
|
|
|
items = [items]
|
|
|
|
|
|
|
|
for i in items:
|
|
|
|
if isinstance(i, Show):
|
|
|
|
display = lambda i: '%s %s %s' % (i.grandparentTitle, i.seasonEpisode, i.title)
|
2017-09-30 22:34:01 +00:00
|
|
|
selected_eps = utils.choose('Choose episode', i.episodes(), display)
|
|
|
|
if isinstance(selected_eps, list):
|
|
|
|
item += selected_eps
|
|
|
|
else:
|
|
|
|
item.append(selected_eps)
|
|
|
|
|
|
|
|
else:
|
|
|
|
item.append(i)
|
2017-09-26 18:11:19 +00:00
|
|
|
|
|
|
|
if not isinstance(item, list):
|
|
|
|
item = [item]
|
|
|
|
|
2017-08-13 05:50:40 +00:00
|
|
|
return item
|
|
|
|
|
|
|
|
|
|
|
|
def get_item_from_url(url):
|
|
|
|
# Parse the ClientID and Key from the URL
|
|
|
|
clientid = re.findall('[a-f0-9]{40}', url)
|
|
|
|
key = re.findall('key=(.*?)(&.*)?$', url)
|
|
|
|
if not clientid or not key:
|
|
|
|
raise SystemExit('Cannot parse URL: %s' % url)
|
|
|
|
clientid = clientid[0]
|
|
|
|
key = unquote(key[0][0])
|
|
|
|
# Connect to the server and fetch the item
|
|
|
|
servers = [r for r in account.resources() if r.clientIdentifier == clientid]
|
|
|
|
if len(servers) != 1:
|
|
|
|
raise SystemExit('Unknown or ambiguous client id: %s' % clientid)
|
|
|
|
server = servers[0].connect()
|
|
|
|
return server.fetchItem(key)
|
2020-05-12 21:26:29 +00:00
|
|
|
|
2023-08-29 03:29:39 +00:00
|
|
|
|
2017-08-13 05:50:40 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
# Command line parser
|
2017-09-26 19:58:56 +00:00
|
|
|
from plexapi import CONFIG
|
2017-08-13 05:50:40 +00:00
|
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
2017-09-26 19:58:56 +00:00
|
|
|
parser.add_argument('-u', '--username', help='Your Plex username',
|
|
|
|
default=CONFIG.get('auth.myplex_username'))
|
|
|
|
parser.add_argument('-p', '--password', help='Your Plex password',
|
|
|
|
default=CONFIG.get('auth.myplex_password'))
|
2020-05-12 21:26:29 +00:00
|
|
|
parser.add_argument('--url', default=None, help='Download from URL (only paste after !)')
|
2017-08-13 05:50:40 +00:00
|
|
|
opts = parser.parse_args()
|
|
|
|
# Search item to download
|
|
|
|
account = utils.getMyPlexAccount(opts)
|
2017-09-26 18:11:19 +00:00
|
|
|
items = search_for_item(opts.url)
|
2017-09-30 22:34:01 +00:00
|
|
|
for item in items:
|
|
|
|
for part in item.iterParts():
|
2022-02-27 03:26:08 +00:00
|
|
|
# We do this manually since we don't want to add a progress to Episode etc
|
2017-09-30 22:34:01 +00:00
|
|
|
filename = '%s.%s' % (item._prettyfilename(), part.container)
|
|
|
|
url = item._server.url('%s?download=1' % part.key)
|
2023-03-10 00:27:30 +00:00
|
|
|
filepath = utils.download(url, token=item._server._token, filename=filename, savepath=os.getcwd(),
|
2017-09-30 22:34:01 +00:00
|
|
|
session=item._server._session, showstatus=True)
|